Why use a doubly-linked list? All the work of a stack is at one end, so a singly-linked list will save you space and time (both coding time and execution time).
We're failing to account for null pointer return here:
Node* updated_head = create_node(elm); if (!s->head) { ⋮ } else { updated_head->next = s->head;
And here:
Stack *s2 = malloc(sizeof *s2); *s2 = stack_init;
Compiling with gcc -fanalyzer reveals these, and running under Valgrind shows failure to free the latter.
I've never, ever, needed to reverse the elements in a stack. Unless you have a compelling use case, drop that function. If you do have such a use, document why it's needed in a comment, so that when it's no longer needed it can be removed.
It's good practice to make all function declarations declare the acceptable arguments:
int main(void) Please use braces consistent for all control structures (if, for, while, do). It makes your code clearer and more resilient to editing.