Sorry for necroing, but this is first article in google on this topic.
Actually its possible and quite easy, unity doing this trough internal class UnityEditor.Menu
.

It has methods to both add and remove menu items

However since its internal class you can access it trough reflections or by creating *.asmref file to make your scripts part of the unity assembly. In assembly reference file you should reference some unity editor assembly, for example UnityEditor.UI
You can create public wrapper to access these internal methods:
using System;
using UnityEditor;
public static class _Menu
{
public static void RemoveMenuItem(string name) => Menu.RemoveMenuItem(name);
public static bool MenuItemExists(string menuPath) => Menu.MenuItemExists(menuPath);
public static void AddMenuItem(string name, string shortcut, bool @checked, int priority,
Action execute, Func<bool> validate)
{
Menu.AddMenuItem(name, shortcut, @checked, priority, execute, validate);
}
}
Then to dynamically add/remove menu you can do something like this:
private const string MENU_PATH = "Asset/SubMenu/Etc";
private static bool MENU_SHOULD_EXIST = true;
[InitializeOnLoadMethod]
private static void Init()
{
EditorApplication.delayCall += VerifyCreateMenu;
}
public static void VerifyMenu()
{
var menuExist = _Menu.MenuItemExists(MENU_PATH);
var menuShouldExist = MENU_SHOULD_EXIST; // Here check your preferences is menu should or should not exist.
// Menu is removed but should be added
if (!menuExist && menuShouldExist)
{
_Menu.AddMenuItem(PATH, "", false, 15,
() =>
{
// Menu execute callback
}, () => true);
}
// Menu exist but should be removed
else if (menuExist && !menuShouldExist)
{
_Menu.RemoveMenuItem(PATH);
}
}
Usage of EditorApplication.delayCall += VerifyCreateMenu;
is required to let unity finish all its native menu population process, else your new menu can get lost.