Your step 2 is performed first. The order is steps 2, 1, 3, 4:
C 2018 6.10.1 4 says [emphasis mine]:
Prior to evaluation, macro invocations in the list of preprocessing tokens that will become the controlling constant expression are replaced (except for those macro names modified by the defined unary operator), just as in normal text…
6.10.1 1 says that the controlling expression of an #if or #elif shall be an integer constant expression which may additionally contain the expressions defined identifier or defined ( identifier ) which:
… evaluate to 1 if the identifier is currently defined as a macro name (that is, if it is predefined or if it has been the subject of a #define preprocessing directive without an intervening #undef directive with the same subject identifier), 0 if it is not.
Thus, first macro replacement is performed, per 6.10.1 4, and later the evaluation of the expression is performed.
Note that, in spite of the fact that macro replacement occurs first, if it generates defined tokens, they are not necessarily evaluated, because 6.10.1 4 goes on to say:
… If the token defined is generated as a result of this replacement process…, the behavior is undefined.
Then your step 3 occurs, again per 6.10.1 4:
… After all replacements due to macro expansion and the defined unary operator have been performed, all remaining identifiers (including those lexically identical to keywords) are replaced with the pp-number 0, and then each preprocessing token is converted into a token…
Then the controlling expression is evaluated, your step 4:
… The resulting tokens compose the controlling constant expression which is evaluated according to the rules of 6.6…