Missing from your list is arguably the most important difference: programming with mathematical (immutable) values. This allows one to build very high-level abstractions and easily reason about correctness. OOP languages simply were not designed for this style of programming.
There are also many other significant differences. I estimate I am about ten times more productive in Haskell than Java.
I don't think mutability is problematic. The problem with mutability is that you can create hidden communication channels between different sections of your code and it can be very difficult to determine what is actually going on without carefully analyzing the entire code base at compile time and at run time for every possible input.
So if you only have mutability inside of a function and it cannot escape, then you have no problems. Or if you have a way to prevent it from crossing module boundaries.
Rust for example, gives you some pretty good tools for controlling mutability and for tracking it. I think this is actually superior to a fully immutable system as with full immutability you end up with other weird problems (like needing monads and monad transformers to do things that would otherwise be simple).
Sure, there's nothing wrong with pure functions that encapsulate mutation, even Haskell supports this, but this isn't how OOP typically works. OOP developers actually use mutation to model the real world, for example a bank balance! Many of their APIs and libraries are designed around mutation, even the default containers. Java got String right though (apart from the UTF16 part).
Strong agree on the "but this isn't how OOP typically works" part.
I think one of the reasons that Rust doesn't have a traditional OO model is because you can't actually enforce mutability controls in that way. At the very least, when I tried to think of how I would find a way to enforce mutable and immutable data using java / c# style OO, I couldn't think of a way that wasn't kind of crazy or hard to use. On the other hand, structs with traits is actually pretty easy to enforce immutable data (hey, this requires a mutable borrow and what you have is an immutable borrow, so compile error).
There are also many other significant differences. I estimate I am about ten times more productive in Haskell than Java.