How it works

ÆfVṢṚḌ Helper link. Argument: k (integer)
Æf Decompose k into an array of primes with product k.
V Eval. Eval casts a 1D array to string first, so this computes the integer
that results of concatenating all primes in the factorization.
Ṣ Sort. Sort casts a number to the array of its decimal digits.
Ṛ Reverse. This yields the decimal digits in descending order.
Ḍ Undecimal; convert the digit array from base 10 to integer.
ÇÇ€=ÇTḟ Main link. Argument: n (integer)
Ç Call the helper link with argument n.
This yields an upper bound (u) for all prime factorization buddies since
the product of a list of integers cannot exceed the concatenated integers.
Ç€ Apply the helper link to each k in [1, ..., u].
Ç Call the helper link (again) with argument n.
= Compare each result to the left with the result to the right.
T Truth; yield all 1-based indices of elements of [1, ..., u] (which match
the corresponding integers) for which = returned 1.
ḟ Filter; remove n from the indices.

\$\begingroup\$I think that Ç€=$ would be a bit faster than Ç€=Ç, given the time constraint.\$\endgroup\$
– Erik the OutgolferJul 18 '17 at 13:58

\$\begingroup\$Thanks, but for input 117, your improvement means the helper link will be called 3331 times instead of 3332 times, so the speed-up isn't measurable. Anyway, the newer (faster) TIO doesn't even need 20 seconds for the combined test cases.\$\endgroup\$
– Dennis♦Jul 18 '17 at 16:13

PowerShell doesn't have any built-ins for primality checking, factorization, or permutations, so this is completely rolled by hand. I worked through a bunch of optimization tricks to try and reduce the time complexity down to something that will fit in the challenge restrictions, and I'm happy to say that I finally succeeded --

Explanation

There's a lot going on here, so I'll try to break it down.

The first line takes input $n and defines a function, f. This function uses accumulative trial division to come up with a list of the prime factors. It's pretty speedy for small inputs, but obviously bogs down if the input is large. Thankfully all the test cases are small, so this is sufficient.

The next line gets the factors of $n, -splits them on every digit ignoring any empty results (this is needed due to how PowerShell does regex matching and how it moves the pointer through the input and is kinda annoying for golfing purposes), then sorts the results in ascending order. We store that array of digits into $x, and use that as the input to a |?{...} filter to pull out only those that are themselves prime. Those prime digits are stored into $y for use later.

We then split $x into two components. The first (i.e., smallest) digit is stored into $a, while the rest are passed into $b. If $x only has one digit, then $b will be empty/null. We then need to re-cast $a as an array, so we use the comma operator quick-like to do so.

Next, we need to construct all possible permutations of the digits. This is necessary so our division tests later skip a bunch of numbers and make things faster overall.

So long as there's element left in $b, we peel off the first digit into $z and leave the remaining in $b. Then, we need to accumulate into $a the result of some string slicing and dicing. We take $a+$y as array concatenation, and for each element we construct a new string $c, then loop through $c's .length and insert $z into every position, including prepending $z$c and appending $c$z, then selecting only the -unique elements. That's again array-concatenated with $a and re-stored back into $a. Yes, this does wind up having goofy things happen, like you can get 3333 for input 117, which isn't actually a permutation, but this is much shorter than attempting to explicitly filter them out, ensures that we get every permutation, and is only very marginally slower.

So, now $a has an array of all possible (and then some) permutations of the factor's digits. We need to re-set $x to be our upper-bound of possible results by |sorting the digits in -descending order and -joining them back together. Obviously, no output value can be larger than this number.

We set our helper array $l to be an array of values that we've previously seen. Next, we're pulling out every value from $a (i.e., those permutations) that are prime, and enter a loop that is the biggest time sink of the whole program...

Every iteration, we're looping from 0 to our upper bound $x, incrementing by the current element $j. So long as the $i value we're considering is not a multiple of a previous value (that's the 0-notin($l|%{$i%$_}) section), it's a potential candidate for output. If we take the factors of $i, sort them, and they -equal $x, then add the value to the pipeline. At the end of the loop, we add our current element $j into our $l array for use next time, as we've already considered all those values.

Finally, we tack on |?{$_-ne$n} to pull out those that are not the input element. They're all left on the pipeline and output is implicit.

Explanation

Concatenating two numbers always gives a bigger result than multiplying them. So the largest number we possibly need to consider is the largest number we can form from the digits of the input's prime factorisation, which is just all digits sorted in descending order. For the given numbers this upper bound is easily small enough that we can exhaustively check every number in range for whether it's a prime factor buddy:

_mf e# Duplicate input N and get a list of its prime factors.
s$ e# Convert the list to a (flattened) string and sort it.
:X e# Store this in X for later.
W% e# Reverse it. This is now a string repesentation of the largest
e# possible output M.
i) e# Convert to integer and increment.
{ e# Get a list of all integers i in [0 1 ... M] for which the following
e# block gives a truthy result.
mf e# Get list of prime factors of i.
s$ e# Get a sorted list of the digits appearing in the factorisation.
X= e# Check for equality with X.
},
^ e# Symmetric set difference: removes N from the output list.

Actually, 27 bytes

Implicit input n.
`...`╗ Define a function and store it in register 0. Call the function f(x).
w Get the prime factorization of x.
"..."£M Begin another function and map over the [prime, exponent] lists of w.
i Flatten the list. Stack: prime, exponent.
$n Push str(prime) to the stack, exponent times.
The purpose of this function is to get w's prime factors to multiplicity.
Σ sum() the result of the map.
On a list of strings, this has the same effect as "".join()
SR≈ Sort that string, reverse it and convert to int.
╜ƒ Now push the function stored in register 0 and call it immediately.
This gives the upper bound for any possible prime factor buddy.
;╝ Duplicate this upper bound and save a copy to register 1.
R Push the range [0..u]
`...`░ Filter the range for values where the following function returns a truthy.
Variable k.
╜ƒ Push the function in register 0 and call it on k.
╛= Check if f(k) == f(n).
Implicit return every value that is a prime factor buddy with n, including n.

Note: I believe the performance requirements are in conflict with the GodeGolf principle. But since there was a rule Your program should solve any of the test cases below in less than a minute, I made two changes to satisfy the rule:

-split'(.)'-ne'' instead the short code |% t*y;

a hashtable for cashing strings.

Each change reduces evaluation time by half. Please do not think that I have used all the features to improve performance. Just those were enough to satisfy the rule.

Japt, 18 bytes

Your Answer

If this is an answer to a challenge…

…Be sure to follow the challenge specification. However, please refrain from exploiting obvious loopholes. Answers abusing any of the standard loopholes are considered invalid. If you think a specification is unclear or underspecified, comment on the question instead.

…Try to optimize your score. For instance, answers to code-golf challenges should attempt to be as short as possible. You can always include a readable version of the code in addition to the competitive one.
Explanations of your answer make it more interesting to read and are very much encouraged.

…Include a short header which indicates the language(s) of your code and its score, as defined by the challenge.

More generally…

…Please make sure to answer the question and provide sufficient detail.

…Avoid asking for help, clarification or responding to other answers (use comments instead).

Code Golf Stack Exchange is a site for recreational programming competitions, not general programming questions. Challenges must have an objective scoring criterion, and it is highly recommended to first post proposed challenges in the Sandbox.