The functional aspects are not really that different. I think the key one is that Erlang has tail call optimization baked in, whereas Scala achieves something close, but not exactly there, by working around the JVM's limitations. Scala's implementation works really well when you have a function calling itself, or two functions mutually calling each other, and that basically supports recursion. But the inability of arbitrary function A -> arbitrary function B -> C -> D, etc, to be used, without risking blowing the stack, does lead to some very simple, easy to understand patterns for control to be unavailable (see Scala actors 'become' below).

From what experience I have (played with Scala, done real dev work in Erlang) -

The lack of inheritance in Erlang/Elixir is a difference. It's one I like (and from what I've seen, the more a person uses Scala the less inheritance they end up using), but others may not.

Actors behave similarly between the platforms, but have a few differences. Whereas in Scala actors (by this I mean Akka) struck me as reactive, in Erlang they struck me as proactive. What I mean is that Scala, at least when I looked at it, it seemed like you create an actor system, and then actors in it, and they do nothing until you send a message. In Erlang, you just create a new process and at any time it can pause to receive a message. That is, the 'actor' is just a thing that does work and has a mailbox, rather than this reactive interconnection of things. Fundamentally there may not be much difference, but I found the abstraction in Erlang easy to initially grok, and playing with Scala led me to some irritation and difficulty in structuring my program. That may have been just due to my own expectations rather than anything innate, but just pointing out, they are a bit different.

Scala actors also have the idea of 'become' when you want to change an actor's behavior (and in general the behavior of an actor feels more rigid to me). In Erlang, an actor is just a process running whatever code. Between that and tail call optimization, the idea of 'become' doesn't exist; if at the end of the function that is executing in the actor's process I want to perform the same action I just recurse; if I want to perform a different action I call a different function. That makes for a very simple mental model to work from; I start an actor and it immediately starts executing (though that execution might just be "wait for a message"), and it runs pretty predictably until either it gets "wait for a message", hits the end of a function (in which case it terminates cleanly), or dies. If you want it to run the same logic more than once you recurse, if you want it to run different logic you call a different function. So the 'actor' part is nothing special, no hand waving or magic, it just is a single process with a mailbox you can check, and I find that delightful to reason about; in Scala actors felt like special ~things~, that I have to configure and then set off.

Performance is a difference; while the JVM is more performant in just sheer number crunching, Erlang has a memory model that better fits actors; there is no stop the world garbage collection. In general, barring something like Azul (which I have no experience with), you'll see a smaller deviation of latencies in Erlang (useful for web servers and things, where every call taking ~5ms is better than having some calls return in 1ms, and others in 120ms).

Scala borrowed a lot of the distribution and fault tolerance mechanisms from Erlang, but I don't like them as much. They feel a bit more bolted on, and the multi-paradigm mixing means a greater degree of rigor is required to ensure you do things properly. That said, Scala seemed to provide a different level of abstractions for supervision strategies, that I didn't really delve into.

The availability of all the JVM libraries is a double edged sword for Scala; while there probably is a JVM library for whatever you want to do, it also probably behaves in ways that won't play nice with your actors, possibly forcing you to deal with multiple concurrency, distribution, and fault tolerance models simultaneously. In Erlang (in which, I might add, I've found libraries for basically everything I wanted to do, that wasn't something extremely esoteric like talk to a piece of hardware that is only used in (X) business domain...of which there was also no Java bindings, only C), unless it's calling out to external code (NIFs and the like), it will at least be informed by the concurrency model you're using (since Erlang it's actors or nothing), though there may be assumptions and expectations and such that the library makes that you will need to understand or modify.This generalizes to the language as a whole, too; in Scala it's very easy to make tradeoffs that will end up hurting you. In fact, it's practically encouraged, as the language is often sold as a way to slowly move into a more functional, safely concurrent world. The problem I have with that is without being forced to move, a lot of devs won't, and mixing paradigms gets you complexity that is usually unnecessary, and oftentimes leads to you not seeing the benefits you'd have gotten had you limited yourself to one.

Another fault tolerance difference (that won't affect you 99% of the time) is that Erlang has better process isolation. An uncaught exception in one process won't affect another one, unless they've been linked together or otherwise been entwined such that they should cause the other to crash. Scala tries to do the same, and largely succeeds, but it doesn't have the same technical underpinnings due to the nature of the JVM.

The profiling/tracing ability of the Erlang VM is better than the JVM (yes, really). The ability to attach a remote shell to poke and prod your running instance is also flat out amazing; I don't recall if Scala had anything similar. I always found Erlang apps to have a fairly small footprint on my box, whereas my experience with the JVM (though mostly using Java) saw them tending to take a fair amount of resources.