rust has `dyn FooTrait`, which lets you do dynamic diapatch, similarly to `FooInterface x = foo();` in e.g. java. even Haskell has a way of doing this via existential types like `(forall a. FooTypeclass a => a)`.
both of these predominantly statically-dispatched langs added ways to do dynamic dispatch later on, which seems to go against "dynamic dispatch could be entirely dropped without losing to much expressiveness". i prefer static-by-default as well, but it looks like it's hard to do without sometimes.
(of course you can always roll your own vtable-ish thing, so technically you could drop DD from the language without loss of expressiveness, but then you'd likely get multiple incompatible libraries for that...)
and i'd guess that some sort of dynamic dispatch is unavoidable if you want to do some kind of plugin architecture