The embed tag combines the behaviour of include and extends. It allows you to include another template’s contents, just like include does. But it also allows you to override any block defined inside the included template, like when extending a template.https://twig.symfony.com/doc/2.x/tags/embed.html

All these functions let you split, reuse and incorporate your code wherever you want but they serve different purposes.

Include lets you extract part of the template for better readability and reusability. It doesn’t have an isolated scope (by default) so the included template has access to the same variables of the parent one. You can also pass additional variables like this

1

{%include'template.html'with{'foo':'bar'}%}

There’s also a way to isolate the scope of the included template but you have to do it explicit using the keyword “only”

1

2

{%include'template.html'only%}

{%include'template.html'with{'foo':'bar'}only%}

Embed lets you incorporate a template but mostly it allows for block overriding so you can include a template but also customize some parts (called blocks) in it.
Embeded templates have access to the current context but you can also pass additional variables:

1

{%embed'embeded_template.html.twig'with{'foo':'bar'}%}

Macro can be considered like a function: it takes some values as inputs and shows the resulting template. It has an isolated scope and you must pass the parameters you require as inputs.
You must declare it and then import it where you want to use it.