SOLVED
Found a solution myself - as it seems, NavigationObstacle2D nodes work correctly. However, after scouring GitHub issues related to my problem, I learned that path taken by NavigationAgent2D does not change when NavigationAgent2D is about to hit a NavigationObstacle2D. What changes in this case is the velocity of the agent. In other words, the path of agent stays the same, but the velocity is changed according to obstacles it encounters and this velocity "pushes" the agent away from the obstacle, thus making the agent avoid the obstacle by going around it.
I also learned that using this approach is not recommended (probably because of resource strain that obstacles present), but my game does not have static obstacles and walls around which I can draw a NavigationRegion. I plan to use procedural generation of levels, so NavigationObstacle2D is currently my best option.
This is how I modified the code:
In _readyfunction I connected to "velocity_computed" signal that is emitted by agent:
navigation_agent.connect("velocity_computed", Callable(self, "move_actor"))
At the end of _physics_process function I get the next path position of agent. This path position * movement speed of agent gives me a velocity that I set in agent:
if not navigation_agent.is_navigation_finished():
var next_move_position = navigation_agent.get_next_path_position() - actor.global_position
actor_velocity = next_move_position * movement_speed
navigation_agent.velocity = actor_velocity
I then added the function that I connected before to "velocity_computed". I named this function "move_actor" that receives the computed velocity from agent and then apply this velocity to my enemy. I also reduce the velocity with (movement_speed / 15) because if I use .normalized() on the received velocity vector, the enemy goes around the obstacle too slow:
func move_actor(velocity :Vector2):
if not navigation_agent.is_navigation_finished():
actor_velocity = velocity
actor.velocity = actor_velocity / (movement_speed / 15)
actor.move_and_slide()
So to sum up, path taken by NavigationAgent2D is not affected by NavigationObstacle2D. Instead, NavigationAgent2D can calculate the velocity needed to avoid the NavigationObstacle2D and this make the agent go around obstacles.