Delegates are user defined datatypes that can be bound to C++ function(s) (or blueprint event(s)) of an object in a generic way. This means that the object need not be even declared for a particular delegate. Let me demostrate.
In Unreal Engine, a delegate is declared like so:
DECLARE_DYNAMIC_DELEGATE_TwoParams(FAnEvent, float, TimeCoordinate, float, SpaceCoordinate);
This just tells the Engine that we are declaring a user defined datatype (a delegate) which can be bound to a C++ routine with two parameters of type float. Now this delegate can be bound to any member function (with signature void (float, float)) of any object.
For demonstration purposes, consider the following code (TP_PickupComponent.h)
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnPickUp, ABPToCodeDemoCharacter*, PickUpCharacter);
Furthermore, we note the blueprint usage property of the delegate (see)
UPROPERTY(BlueprintAssignable, Category = "Interaction")
FOnPickUp OnPickUp;
Finally, we observe the application of the delegate here, like so
void UTP_PickUpComponent::OnSphereBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
// Checking if it is a First Person Character overlapping
ABPToCodeDemoCharacter* Character = Cast<ABPToCodeDemoCharacter>(OtherActor);
if(Character != nullptr)
{
// Notify that the actor is being picked up
OnPickUp.Broadcast(Character);
// Unregister from the Overlap Event so it is no longer triggered
OnComponentBeginOverlap.RemoveAll(this);
}
}
This basically translates to the meaning that when the overlap detector of the pickup detects, well, an overlap with player’s character (no pun intended), then notify all the registered events (bound to OnPickUp variable of type delegate defined above) and run the appropriate logic in their respective classes.
The blueprint equivalent of registering event by binding to OnPickUp delegate (.AddDynamic()) is like so (Bind Event On Pick Up node)

The blueprint equivalent of
OnPickUp.Broadcast(Character);
is Call On Pick Up node

A nice property of the delegates is that they can be used in appropriate arbitrary classes (mentioned above). Look at the call to Binding Delegates node, which is a function of class ABPToCodeDemoCharacter (which is not declared or defined where the delegate is declared). The function is defined like so

We can see that an event AnEvent is bound to OnPickUp in the class even though OnPickUp is not declared/defined in the class. The event is like so

Checkout the commit Delegate demonstration (literally :D) to see the logic in action.
A fun fact I saw while working in Sunovatech Pvt. Ltd is that delegate can be passed as a C++ function parameter https://forums.unrealengine.com/t/delegates-as-parameter/299175/13.