systemd makes it the most easy. all you need is systemctl switch-root ROOT. on other inits, you usually need to replace /sbin/init, then use some non-portable (sysvinit is not the only competitor) method of telling init to re-exec itself. sometimes that method doesn't even stop the running services, so you need to either manually stop them, or kill them.
You can do it non-destructively by bind mounting a binary from ramfs over /bin/init
When it reexecs, the new binary can kill and umount everything and switch roots. If it fails somehow, you just reboot and everything is back to normal.