A worthy project is to take some of these constructs, like the FSMs and synthesize them. Then look at the RTL schematic. The synthesizer will warn you if you have inferred a latch but what it won't tell you is whether you have inferred a priority encoder and whether that priority encoder is realized as a long string of logic which doesn't help with Fmax.
I don't disagree that case statements are preferable when you have many possible states. Personally I would restrict it to one or a few signal assignments per process and enforce that every branch of the "case" has exactly the same assignments. Never think of it as "control flow" like in programming; a case statement with signal assignments is a mux.
Regarding big state machines, the answer is avoid them in optimized designs
. Inherently a big state machine with many inputs will generate a big combinatorial circuit, which is always going to mess up your timing. Instead, design the system as many smaller "building blocks", where each building block may have small state machines.
I still prefer to see all possible sources of a signal, rather than all things that "happen" at a state because this way tells me right away what the circuit is like and any possible timing bottlenecks. When I need to reason about the design, I don't read the code, I go back to the diagram.
Btw I don't think of it as a single "machine" that does "actions"; rather a circuit that has some state variables, plus some independent "circuit fragments" that data passes through and may behave differently depending on the state. When I look at an output-forming circuit, the possibilities of the circuit are more relevant than other circuits that happen to change their behavior during the same state. In other words, I don't think the output forming logic are part of the state machine, and different output forming circuits may be completely independent (e.g. the part generating sync signals vs the part that computes next synthesizer frequency).