See this question for how to do it programmatically. The trick is to set the ContextMenu on whatever control you set as the header content. If you're just using the header to set a simple string value, that won't work. At minimum you'll need to create a TextBlock or ContentControl or something.
For those interested in how to do it via XAML (particularly when using MVVM pattern):
Set a ContextMenu on the TabControl's ItemContainerStyle. It will then only apply to actual tab part (the header) and not the tab content. You can use bindings and such on the MenuItems to get varied behavior based on the specific tab, provided your tab is using a ViewModel..
<TabControl>
<TabControl.ItemContainerStyle>
<Style TargetType="{x:Type TabItem}">
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu/> <!-- Define it here! -->
</Setter.Value>
</Setter>
</Style>
</TabControl.ItemContainerStyle>
</TabControl>