Nevermind, I figured it out myself.
I have a global LevelManager script that emits the level_change_started signal when the player enters a transition area and a level_loaded signal after the new scene is loaded and the fade animation is finished. Then I connected the level_change_started signal to the following function in my player camera script:
func level_change_started() -> void:
position_smoothing_enabled = false
limit_smoothed = false
await LevelManager.level_loaded
position_smoothing_enabled = true
limit_smoothed = true
force_update_scroll()
reset_smoothing()
reset_smoothing()
I also call a similar procedure in the camera's ready function, but I replaced the LevelManager.level_loaded signal with the get_tree().process_frame signal.