Erlang, Elixir, Swift, Rust, Python, probably some others.
That list is roughly in order of how capable and useful the pattern matching is in each of those languages. Erlang was originally written in Prolog.
Also, I definitely agree it's a feature I miss everywhere when not using Erlang/Elixir.
I looked at Erlang and it is closest to the Prolog idea (clearly because Erlang was originally implemented in Prolog). Other languages are not really what I mean by pattern matching, the matching should go on the selection of functions to apply to a particular parameter expression. In the compiled world, C++ is the one that gets closest to this behavior. Python would be able to do it due to its dynamic nature, but for some reason it decided not to implement this feature.
I'm curious, how does Swift have better pattern matching than Rust?
I mostly ignored Python until my job required it, about 8 years ago. Coming from Erlang, I was pleasantly astonished to find that I could use tuple pattern matching in function headers… until I discovered that was dropped in Python 3 and I had been using the mostly-dead version 2 runtime.