Looking at the script room_enter_menu_maintaining_game_state should give you some ideas, it does a couple of things:
- save the screen to a surface so the levelup menu can have the game in the background,
- set the room to persistent, and
- set up the player alarm which later turns off persistence again once you return to that room. (This alarm also is what applies all confirmed upgrades once you're back in the room)
After doing all that it changes the room to the one with the levelup menu - the game basically pauses by changing to a different room, but using persistence to maintain the state of the original room.
Also note obj_upgradecontrol, its regular Draw event draws this screenshot in the background (and then the menu is drawn on top), your pause menu would probably do something similar (or at least draw the screenshot + some static text that reads "paused")
As long as you make sure global.confirmed_upgrades is empty you should be able to just reuse this functionality wholesale (change rooms to the pause screen with room_enter_menu_maintaining_game_state, keep track which room you were in before you swap, and go back to that room when done), but the only things that really are needed are setting the room to persistent before you leave and setting up an alarm to turn off persistence once you're back.