The fallback function equips a contract with the possibility of handling function calls dynamically.
A common use case is to program the fallback function on a front-facing “proxy” contract to delegate all received calls to an “implementation” contract. This pattern is often used to implement a contract upgrade mechanism, e.g. here. The front-facing contract is deployed once in the beginning and its address will never change for the user, but the address of the implementation contract which it points to will be configurable.
Since the fallback function will delegate any function call it receives, and not only the calls to functions that existed when the proxy contract was deployed, it is possible to deploy a new implementation that has a brand new function, and after configuring the proxy to point to this new implementation, it will be possible to call that function on the original proxy, and the proxy fallback function will delegate it as expected. This would not be doable without the fallback function.