A few options.
If your controller state variables are all pretty much needed across the entire massive flow, keep all your postback methods in one controller, but delegate their implementation to other classes that manage the logic. Example:
public PageReference step9() {
return Step9Controller.go(param1, param2, ...); // this is a static method on some delegated class
}
If your shared state only needs to pass a few variables from controller to controller, divide your controllers at the points where shared state is minimal, and pass as query parameters:
public PageReference step9() {
// do your implementation here
return new PageReference('/Step10?p1=' + param1 + '&p2=' + param2); // this page is backed by the next controller
}
If neither of those options is attractive (maybe you don't have that much shared state, but you also don't want to expose the variables to the user), you can save the state to a table row and pass that ID to the next controller:
public PageReference step9() {
// do your implementation here
Wizard_State__c next = Wizard_State__c(Param1__c = param1, Param2__c = param2); // or whatever you need
insert next;
return new PageReference('/Step10?nextId=' + next.Id); // this page is backed by the next controller
}
There are a few other ways to handle it too, but those are the ones I'd opt for.