I dropped the Area2D idea. I set a RigidBody on "character" mode, gravity direction to 0, 0, reported contacts to 1. I get the collision normal in the Physics2DDirectBodyState.
var bodyState:Physics2DDirectBodyState
# The signal "body_entered" is connected to this function.
func _on_Ball_body_entered(body):
# I guess the contact array always contains a value at index 0, because a body has entered,
# maybe a null check before this call would be safer.
collNorm = BodyState.get_contact_local_normal(0)
func _integrate_forces(state):
bodyState = state
The ball behaves like I want now. I'm not sure to get the full control of translations as I searched with the Area2D, so it needs some experiment. At least, the question in the title is answered.