I don't think there's a good answer to this, unfortunately.
As you say, the filter() option gives a list of Pair<T?, U?> where the compiler still thinks the pair's values can be null even though we know they can't.
And the mapNotNull() option fixes that, but needs new Pair objects to be created, which is inefficient. (The !! there are ugly, but I think this is one of the times when they're justified. It's a shame that the compiler's smart casts aren't smart enough, but I understand that total type inference is an intractable problem, and it has to stop somewhere.)
I found a third option, which fixes both of those problems, but at the cost of an unsafe cast:
fun <T, U> List<Pair<T?, U?>>.filterNotNull()
= mapNotNull{ it.takeIf{ it.first != null && it.second != null } as? Pair<T, U> }
Like the second option, this uses mapNotNull() to both filter and convert the pairs; however, it does a simple cast to tell the compiler that the type parameters are non-nullable. This returns a Pair<T, U> so that the compiler knows the pair values cannot be null, and it avoids creating any new objects (apart from the overall list, of course).
However, it gives a compile-time warning about an unsafe cast. It runs fine for me (Kotlin/JVM), but like all unsafe casts there's no guarantee it will work on all platforms or all future versions. So it's not ideal.
All three options have drawbacks. Perhaps the best overall is your second option; the code itself is a little ugly, and inefficient (creating new Pairs), but it's safe, will always work, and is nice to use.
(By the way, I think filterNotNull() would be a better name for this function. In the standard library, filter functions seem to be named for what they keep, not what they drop, so filterAnyNulls() would give completely the wrong impression!)