text:
Close-Knit Words
Introduction
According to Rand Al'Thor's post in the Puzzling SE, a close-knit word is any word that contains three alphabetically consecutive letters (in any order).
Words like education, foghorn and cabaret are all considered close-knit words whereas words like learning, klaxon and perform are not close-knit words.
Challenge
The challenge is to code-golf a program capable of taking a single word as input (assumed lower case, for all intents and purposes) and to return output that (if available) lists all consecutive letter sets (also in lower case) if it is a close-knit word, and empty output if it is not a close-knit word.
Examples
Input: education
Output: cde

Input: foghorn
Output: fgh

Input: cabaret
Output: abc

Input: hijacking
Output: ghi, hij, ijk

Input: pneumonia
Output: mno, nop

Input: klaxon
Output: <<no output>>

Input: perform
Output: <<no output>>

Input: learning
Output: <<no output>>

Rules

Whereas input is to be assumed to be a single lower-case word and output must be lower-case, the nature of the output will vary according to the choice of your coding language. Please select a form of output that will best suit the nature of the challenge, whether it be STDOUT, file output, array, etc.
Because this is code-golf, it will be a case of lowest number of bytes being the clear winner.
No silly loopholes.
I will not accept answers that have the consecutive letters in non-alphabetical order... So cab will not be deemed a suitable output for cabaret, for example.
Special note, while the "triplets" don't necessarily have to be in alphabetical order, but the characters within the triplets must be... so in the case of the word "performance", for example, the output mno,nop will be accepted, as will nop,mno. In the case of the word "hijacking", there are six ways that the triplets of ghi, hij and ijk could be arranged in a list, and all six permutations are acceptable as output.

Other than that, on your marks, get set, golf!

Can the output be a 2D char array with each set of three consecutive letters in a column?

@LuisMendo Can you give me an example just so that I can visualize it?

Try my code without the final ! And with another word, as the current one gives the same result :-)

@LuisMendo is MATL column major or something?

@Maltysen Yes, like Matlab. And many functions operate on columns by default

@LuisMendo I've taken a look at the corresponding output without the !, and I don't think it reads very well... I don't think I could accept that... Especially if you ran it with a word like "pneumoultramicroscopicsilicovolcanoconiosis"

Is a trailing , accepted?

@Titus Sounds like you'd be outputting a string as a comma separated list... I'll accept it, but please make note of the trailing comma in your entry...

Please note the final rule, allowing permutations of the outputted triplets. If displaying your output improves your score in this manner, I suggest you work it to your advantage.

Is an output in the format of an array of tuples okay, i.e. the output for pneumonia can be [('m','n','o'),('n','o','p')])?

@R.Kap I'll allow that :) Looking forward to setting your entry!

What about an output like this for input hijacking? I hope I'm not pushing the limits too much now...

Acceptable :) It clearly defines the boundaries between each tuple, so go for it.

Hopefully the last inquiry: May I accept only uppercase input? I know it's stated in the post, but you do use the word assumed, so I just want to be sure about that...

@R.Kap I've mentioned that input and output are preferred to be lower case... Go with what works for you in this case. :)

All right! I really appreciate the flexibility with the input and output methods. :)

Sorry for all these questions, but will there ever be an input of only three consecutive letters, i.e. cde or abc?

Well, it could be possible, but like I said, we'd be dealing with a word that would be composed of such a tuplet... I think the only word that comes to mind that would fit such criteria would be cab which would render out abc as output...

05AB1E, 7 6 5 bytes
Code:
3ãAŒÃ

Explanation:
3ã      # Cartesian product × 3 with input
  AŒ    # All substrings of the alphabet
    Ã   # Setwise intersection

Uses the CP-1252 encoding. Try it online!

This is just sheer genius... I'll have to try creating a challenge that pushes this language to the limit... ;)

Python 3.5, 68 bytes
w=input()
a=0
while 1:s='%c'*3%(a,a+1,a+2);a+=1;{*s}-{*w}or print(s)

Prints output strings, and terminates with error when the character value gets too large.
Generates all strings of three consecutive and prints those that are a subset of the input word.

Pyth - 11 10 8 7 bytes
Super brute force method.
@^z3.:G

Test Suite.
@            Setwise intersection, finds common strings between the two lists
 ^           Cartesian product
  z          Input
  3          Of length 3
 .:          Substrings. Without second input finds all substrings which is ok
  G          Lowercase aphabet

JavaScript (ES6), 95 90 bytes

f=
s=>[...s].map(c=>a[parseInt(c,36)]=c,a=[])&&a.map((c,i)=>c+a[i+1]+a[i+2]).filter(c=>!c[3])
;
<input oninput="o.textContent=f(this.value).join`, `"><div id=o>

Missing values concatenate as undefined, so the resulting string contains greater than 3 characters. I borrowed the !c[3] trick from @ETHproductions to save 5 bytes.

Coincidentally enough undefined is a close-knit word ;)

Why parseInt(c,36) instead of c.charCodeAt()?

@Titus I guess it makes no difference, I'm just used to using parseInt in code golf.

Jelly, 7 bytes
ØaẆfṗ3$

This is a monadic link. Try it online!
How it works
ØaẆfṗ3$  Monadic link. Argument: s (string)

Øa       Yield the lowercase alphabet, i.e., a := "abcdefghijklmnopqrstuvwxyz".
  Ẇ      Window; yields all substrings of a.
      $  Combine the two links to the left into a monadic chain.
    ṗ3   Take the third Cartesian power of s, yielding all combinations of three
         characters that can be formed from the letters in s.
   f     Filter; keep only those substrings of a that appear in the Cart. power.

C, 175 174 bytes
main(_,a,m,n)char**a;{char*s=a[1],*t=s;while(*++s)while(s>t&&(n=s[-1])>=*s){m=(*s^n)?*s:0;*s=n;*--s=m;!*t&&++t;}for(;t[1]&t[2];++t)*t==t[1]-1&&*t==t[2]-2&&printf("%.3s ",t);}

indented:
main(_,a,m,n)char**a;
{
  char*s=a[1],*t=s;
  while(*++s)
    while(s>t&&(n=s[-1])>=*s){
      m=(*s^n)?*s:0;
      *s=n;
      *--s=m;
      !*t&&++t;
    }
  for(;t[1]&t[2];++t)
    *t==t[1]-1&&*t==t[2]-2&&printf("%.3s ",t);
}

While doing the sort it replaces duplicate values with 0s, these 0s get sorted to the beginning of the word. Looking for the consecutive values is then trivial.

Welcome to the site!

Yes, welcome to PPCG! Great work on your answer, C is not one of the easiest to golf in!

Haskell, 48 bytes
f w=filter(all(`elem`w))[take 3[c..]|c<-['a'..]]

Generates all triples of three consecutive characters, takes those that use only letters in the input.

53 bytes:
f w=filter(all(`elem`w))[[pred$pred c..c]|c<-['c'..]]

The list ['c'..] contains all unicode characters from 'c' onward. The list comprehension [[pred$pred c..c]|c<-['c'..]] turns them into all strings of 3 consecutive characters from "abc" onward. We step backwards with [pred$pred c..c] instead of forwards with [c..succ$succ c] to avoid an error when taking the successor of the highest unicode character.
These triples are filtered for those that only use letters in the input.

Great answer! I tried making it pointfree, but alas, it's still 48 bytes

PHP, 100 bytes
for($a="abc",$i=98;$i<123;$a=substr($a,1).chr(++$i))if(strstr(count_chars($argv[1],3),$a))echo"$a,";

takes input as command line argument; prints a trailing comma. run with -r.

for($s=join(range(Z,z));$a=substr($s,++$i,3);) is a shorter way of creating $a. It admittedly checks a bunch of punctuation and also some 2-character series but as the input is lower case letters only and it requires that it finds 3 characters that's fine.

for($a="ab",$i=98;$i<123;)!strstr(count_chars($argv[1],3),$a=substr($a,1).chr(++$i))?:print"$a,";` saves 2 Bytes. Very nice way, I have tried other ways in PHP but can't reach the Bytes of your code. I'm not sure if you need a space after the comma

Python 3.5, 78 bytes
s={*input()}
for c in s:o=ord(c);a=chr(o-2);b=chr(o-1);s>{a,b}and print(a+b+c)

T-SQL, 153 bytes
Had to react on the comment from WallyWest, about it being long time since last TSQL answer. Answer was partly inspired by Brian J's answer
Golfed:
USE MASTER
DECLARE @ varchar(max)='hijacking'

;WITH C as(SELECT distinct ascii(substring(@,number,1))z FROM spt_values)SELECT CHAR(C.z)+CHAR(D.z)+CHAR(E.z)FROM C,C D,C E WHERE c.z+1=d.z and d.z=e.z-1

Fiddle
Ungolfed:
USE MASTER -- can be left out if the master database is already being used
DECLARE @ varchar(max)='hijacking'

;WITH C as
(
  SELECT distinct ascii(substring(@,number,1))z
  FROM spt_values
)
SELECT CHAR(C.z)+CHAR(D.z)+CHAR(E.z)
FROM C,C D,C E
WHERE c.z+1=d.z and d.z=e.z-1

That's clever! Didn't even know about that table. Good thing there aren't words more than 2048 letters long!

MATL, 13 bytes
2Y23YCtjmAZ)!

Try it online!
2Y2    % Push string of lowercase alphabet
3YC    % 2D char array with sliding blocks of size 3, each on a column
t      % Duplicate
j      % Take input
m      % Member function: true for elements of the 2D array that are in the input
A      % All: true for columns that consist of all true values
Z)     % Use as logical index into the columns of the 2D char array
!      % Transpose. Implicitly display

Perl, 36 bytes
Includes +1 for -n
Give input on STDIN:
perl -nE 'join("",a..z)=~/[$_]{3}(?{say$&})^/' <<< "hijacking"

Just the code:
join("",a..z)=~/[$_]{3}(?{say$&})^/

Actually, 13 bytes
Golfing suggestions welcome. Try it online!
S3@╧`εj`M3úV∩

Ungolfing
                Implicit input string s.
S               sorted(s).
 3@╧            Push all length-3 combinations of s.
    `εj`M       Join all of those combinations into single strings.
         3úV    Push all slices of the lowercase alphabet of length 1 <= n <= b
            ∩   Push the intersection of the combinations and slices.
                Implicit return.

Scala, 59 bytes
(s:Set[Char])=>'a'to'z'sliding 3 filter{_.toSet subsetOf s}

Ungolfed:
(s:Set[Char]) => ('a' to 'z').sliding(3).filter{threeChars => threeChars.toSet.subsetOf(s)}

Explanation:
(s:Set[Char])=>             //define a function with a Set of Chars called s as an argument
'a' to 'z'                  //create a Range of characters 'a' to 'z'
sliding 3                   //create an Iterator(Seq(a, b, c), Seq(b, c, d), Seq(c, d, e), ... , Seq(x, y, z))
filter{_.toSet subSetOf s}  //keep only the triplets which are a subset of s

Haskell, 63 60 52 bytes
f w=[x|x<-take 3<$>scanr(:)"_"['a'..],all(`elem`w)x]

Usage example: f "hijacking" -> ["ghi","hij","ijk"].
scanr(:)"_"['a'..] builds a list with the tails of the list of all unicode chars starting with 'a' and lets it end with a '_', i.e. ["abcde...\1114111_", "bcde...\1114111_", "cde...\1114111_", ..., "\1114109\1114110\1114111_", "\1114110\1114111_", "\1114111_", "_"]. Then we take up to three chars of each string and bind it to x. Keep all x where every letter of it is in the input parameter w.
Edit: @xnor saved 3 7 bytes. Thanks!

Does anyone know if I can capture the first three elements of the list a:b:c:_ with an @-pattern?

I don't know about the @-pattern, but you can remove the 'z' upper bound and just let it try all characters.

Capturing those first 3 elements is really annoying. Best I can see is just to use take and remove the empty string: f w=[x|x<-init$take 3<$>scanr(:)""['a'..],all(`elem`w)x]

@xnor: nice. we can start the scanr with "." instead of "" and omit the init$.

Python 3.5, 114 111 88 80 79 bytes:
lambda X,W=[*map(chr,range(65,91))]:[i*({*X}>={*i})for i in zip(W,W[1:],W[2:])]

An anonymous lambda function. Takes input as an uppercase string and outputs an array of tuples, with the ones filled with three uppercase characters representing all sets of 3 consecutive letters that appear in the input. For example,
[(), (), (), (), (), (), ('G', 'H', 'I'), ('H', 'I', 'J'), ('I', 'J', 'K'), (), (), (), (), (), (), (), (), (), (), (), (), (), ()]

would be the output for input HIJACKING. This output format has been confirmed to be okay by OP. So has the only uppercase input format. However, if you want to input in only lowercase, simply replace range(65,91) with range(97,123), adding one more byte.
Repl.it with all Test Cases!
Explanation:
Basically what is happening here is:

A list, W, is created using W=[*map(chr,range(65,91))], which contains all the uppercase letters in the English alphabet. Because of this, an uppercase input is always required.
For each tuple, i, in a list, which we will call U, containing all three consecutive letter tuples, i.e.:
U=[('A','B','C'),('B','C','D'),('C','D','E'),...]

created by zip(W,W[1:],W[2:]), each i is fully added to the output list as long as all elements in the set version of i ({*i}) are in the set version of input X ({*X}), i.e. {*X}>={*i}, i.e. X is a superset of i. Otherwise, the empty version of i (()) is added to the list.
Once all the tuples have been gone through with the matches fully added, the list is returned as the final output.

T-SQL (SQL Server 2014), 217 bytes
Golfed
declare @ table(a char)declare @i int=1while @i<=len(@a)begin insert into @ values(SUBSTRING(@a,@i,1))set @i+=1 end select distinct t.a+u.a+v.a from @ t,@ u,@ v where ASCII(t.a)+1=ASCII(u.a)and ASCII(u.a)+1=ASCII(v.a)

Usage
First declare the variable @a as a char of some sort and assign the input like so
declare @a varchar(max) = 'pneumoultramicroscopicsilicovolcanoconiosis'

I didn't count the declare as part of my code, but I didn't find a sql standard for input, so I'm willing to change my counting
Output will either be one row for each triple, or no rows if the word is not close knit
Ungolfed
declare @temp table ( letter char(1) ) -- table to hold each letter of the word

declare @i int = 1

while @i <= len(@input) -- split each letter, and each row in @temp will have one letter
begin
    insert into @temp values (SUBSTRING(@input, @i, 1))
    set @i = @i + 1
end

-- join the letters table to itself to get three letter triples, where the three are in adjacent increasing order
-- use distinct because there might be duplicates in the word
select distinct t1.letter + t2.letter + t3.letter
from @temp t1
cross apply @temp t2
cross apply @temp t3
where ASCII(t1.letter) + 1 = ASCII(t2.letter)
and ASCII(t2.letter) + 1 = ASCII(t3.letter)

the declaration wouldn't be counted seeing we're dealing with the code that would be required to execute the required functionality post-declaration in this instance. Great work, been a while since I've seen an SQL solution for a challenge. Great work!

I have golfed your script down to 185 characters, here is the ungolfed version. You may want to check out my answer as well

R, 220 bytes
My solution is pretty straightforward. It loops through the possible three letter combinations, loops through and checks the characters of the entered string against the three consecutive letters, and adds them to a string. The string is then only printed when three letters are found (c==4).
f<-function(w){if(nchar(w)>2){for(i in 1:24){
c<-1
t<-""
for(k in 1:3){for(j in 1:nchar(w)){if(substr(w,j,j)==intToUtf8(95+k+i)&c<4){
t<-paste(t,substr(w,j,j),sep="")
c<-c+1
break
}}}
if(c==4){print(paste(t))}}}}

input/output
> f("education")
> [1] "cde"
> > f("foghorn")
> [1] "fgh"
> > f("cabaret")
> [1] "abc"
> > f("hijacking")
> [1] "ghi"
> [1] "hij"
> [1] "ijk"
> > f("pneumonia")
> [1] "mno"
> [1] "nop"
> > f("klaxon")
> > f("perform")
> > f("learning")
> >

Racket 237 bytes
(define(f s)(let((lr(λ(l i)(list-ref l i)))(l(sort(map char->integer(string->list s))<)))(for((i(-(length l)2)))
(when(=(-(lr l(+ i 2))(lr l(+ i 1)))1(-(lr l(+ i 1))(lr l i)))(for((j 3))(display(string(integer->char(lr l(+ i j))))))))))

Testing:
(f "education")

Output:
cde

Detailed version:
(define(f2 s)
  (let ((lr (λ(l i)(list-ref l i)))
        (l (sort (map char->integer (string->list s)) <)))
  (for ((i (-(length l)2)))
    (when (=  (- (lr l (+ i 2)) (lr l (+ i 1)))
              1
              (- (lr l (+ i 1)) (lr l i)))
      (for((j 3))
        (display (string(integer->char (lr l (+ i j))))))))))

Java 7, 230 bytes
String c(char[]q){java.util.Arrays.sort(q);char a[]=new String(q).replaceAll("(.)\\1","$1").toCharArray(),c=97,i=2;String r="",z="",s;for(;c<'z';z+=c++);while(i<a.length)if(z.contains(s=""+a[i-2]+a[i-1]+a[i++]))r+=s+" ";return r;}

This can most likely be golfed, but the challenge was a lot tougher than I originally thought in Java..
Ungolfed & test cases:
Try it here.
class M{
  static String c(char[] q){
    java.util.Arrays.sort(q);
    char a[] = new String(q).replaceAll("(.)\\1", "$1").toCharArray(),
         c = 97,
         i = 2;
    String r = "",
           z = "",
           s;
    for(; c < 'z'; z += c++);
    while(i < a.length){
      if(z.contains(s = "" + a[i-2] + a[i-1] + a[i++])){
        r += s+" ";
      }
    }
    return r;
  }

  public static void main(String[] a){
    System.out.println(c("education".toCharArray()));
    System.out.println(c("foghorn".toCharArray()));
    System.out.println(c("cabaret".toCharArray()));
    System.out.println(c("hijacking".toCharArray()));
    System.out.println(c("pneumonia".toCharArray()));
    System.out.println(c("klaxon".toCharArray()));
    System.out.println(c("perform".toCharArray()));
    System.out.println(c("learning".toCharArray()));
    System.out.println(c("dblacghmeifjk".toCharArray()));
  }
}

Output:
cde
fgh
abc
ghi hij ijk
mno nop

abc bcd cde def efg fgh ghi hij ijk jkl klm

Just have to ask why Java? It isn't the most golfable of languages...? +1 for effort of course...

@WallyWest Well, I'm a Java developer in everyday life. And I know I will never win any challenge with how verbose Java is, but it's still fun to codegolf in Java imho. :)

guess ill have to come up with a few creative code challenges in the near future for you to participate :) good work nevertheless!

JavaScript (Firefox 48), 93 bytes
x=>[for(c of a=[...new Set(x,i=0)].sort())if(parseInt(d=c+a[++i]+a[i+1],36)%1333==38&!d[3])d]

This lends itself to a 96-byte ES6 version:
x=>[...new Set(x)].sort().map((c,i,a)=>c+a[i+1]+a[i+2]).filter(x=>!x[3]&parseInt(x,36)%1333==38)

How it works
The first major chunk of the function is this:
[...new Set(x)].sort()

new Set(string) creates a Set object that contains one of each unique character in the string. For example, new Set("foghorn") will return Set ["f", "o", "g", "h", "r", "n"]. We can convert this into an array with [... ], then sort it with the built-in .sort(). This turns "foghorn" into ["f", "g", "h", "n", "o", "r"].
The next step is this:
.map((c,i,a)=>c+a[i+1]+a[i+2])

This maps each character in the array to the character concatenated with the two items after it. For example, ["f", "g", "h", "n", "o", "r"] => ["fgh", "ghn", "hno", "nor", "orundefined", "rundefinedundefined"]. (The undefineds pop up when you try to access a non-existent member of the array.
The final step is filtering:
.filter(x=>!c[3]&parseInt(x,36)%1333==38)

First, the !c[3]& is to rule out any strings that contain undefined. This is necessary because a bug causes the following algorithm to count e.g. gmundefined as a consecutive triplet.
All three-consecutive-char strings, when interpreted as base-36 numbers, are 38 modulo 1333. I figured this out by the following calculation:

012 (base 36) =   38
123 (base 36) = 1371
1371 - 38 = 1333
1371 mod 1333 ≡ 38 mod 1333 ≡ 38

Therefore, if a three-char string is 38 mod 1333 in base-36, the three characters are consecutive in the alphabet.
Test snippet

function test(x){O.innerHTML=/[^a-z]/.test(x)?"Invalid input":f(x);}
f=x=>[...new Set(x)].sort().map((c,i,a)=>c+a[i+1]+a[i+2]).filter(x=>!x[3]&parseInt(x,36)%1333==38)
<input id=I value="hijacked">
<button onclick="test(I.value)">Run</button>
<pre id=O>cde,hij,ijk</pre>

This fails for words such as gem and mage.

So you're saying that all consecutive letter triplets when converted back from hexatrigesimal (base 36) are 38 when mod'd against 1333... that is freaking awesome!

@Neil Fixed at the cost of six bytes.

I appropriated your !c[3] trick which brought down my ES6 answer to the length of your previous ES6 answer, so now I'm even outgolfing your Firefox 30+ answer. Sorry about that.

@Neil I don't mind :)

PowerShell v2+, 93 bytes
param($n)97..120|%{-join[char[]]($_,++$_,++$_)}|?{(-join([char[]]$n|sort|select -u))-match$_}

Feels much longer than required, but I can't seem to golf it any further.
Takes input $n. Loops from 97 to 120, constructing contiguous three-letter strings -- that is, up to the |?, we'll have abc, bcd, cde, etc. on the pipeline. Then that's fed through a Where-Object (the |?) to pull out only those items where the clause is true. Here, the clause is 1) the input string $n, cast as a char-array, sorted and select -unique'd, then -joined back into a string, 2) -matched against the three-letter strings (i.e., regex matching). If it's a match, then the three-letter string is in the word, and so it filters through the |?. The results are left on the pipeline and output is implicit.
Examples
(Note that here the output is space-separated, since we're stringifying the output by concatenation.)
PS C:\Tools\Scripts\golfing> 'education','foghorn','cabaret','hijacking','pneumonia','klaxon','perform','learning'|%{"$_ -> "+(.\close-knit-words.ps1 $_)}
education -> cde
foghorn -> fgh
cabaret -> abc
hijacking -> ghi hij ijk
pneumonia -> mno nop
klaxon ->
perform ->
learning ->

Great explanation. I'd give you two up votes if possible.

Retina, 106 56 bytes
D`.
O`.
^
abc¶
{`^(.*)¶.*\1.*
$0¶$1
}T`_l`l;`^.*
2`.*¶?

Deduplicate, Sort. Add abc. Find if the substring is found and append if so. Translate to next substring. Repeat. Then remove first two lines.
Try it online

Naive solution:
D`.
O`.
!&`abc|bcd|cde|def|efg|fgh|ghi|hij|ijk|jkl|klm|lmn|mno|nop|opq|pqr|qrs|rst|stu|tuv|uvw|vwx|wxy|xyz

Deduplicate, Sort, then output overlapping matches of 3 sequential letters.
Try it online

The naïve solution looks pretty straightforward... though I like your golfed solution better... well done!

Ruby, 50 bytes
each_cons(3) gets all consecutive sublists of length 3 from the alphabet ?a..?z, then use e&s.chars==e to select only the ones that have all characters in the target string by using setwise intersection. Returns a list of lists.
->s{(?a..?z).each_cons(3).select{|e|e&s.chars==e}}

Try it online!

[R], 110 bytes
 f=function(b){a=combn(sort(utf8ToInt(b)),3);apply(unique(t(a[,which(apply(diff(a),2,prod)==1)])),1,intToUtf8)}

I'm sure its still golfable

Japt, 10 9 bytes
;Cã3 fUá3

Try it or run all test cases
;Cã3 fUá3     :Implicit input of string U
;C            :Lowercase alphabet
  ã3          :Substrings of length 3
     f        :Filter elements contained in
      Uá3     :Permutations of U of length 3


text:
Prime factors buddies
Given an integer N > 1, output all other numbers which prime decompositions have the same digits as the prime decomposition of N.
For example, if N = 117, then the output must be [279, 939, 993, 3313, 3331], because
117 = 3 × 3 × 13

therefore, the available digits are 1, 3, 3 and 3 and we have
279  = 3 × 3 × 31
939  = 3 × 313
993  = 3 × 331
3313 = 3313
3331 = 3331

Those are the only other possible numbers, because other combination of these digits yield non-prime integers, which can't be the result of prime factorization.
If N is any of 117, 279, 939, 993, 3313 or 3331, then the output will contain the five other numbers: they are prime factors buddies.
You cannot use leading zeroes to get primes, e.g. for N = 107, its only buddy is 701 (017 is not considered).
Input and Outputs

The input and output buddies must be taken and returned in the decimal base.
N will always be strictly greater than 1.
The output can be formatted rather freely, as long as it only contains the buddies and separators/list syntactic elements.
The ordering of the output is unimportant.
You may take the input through STDIN, as a function argument or anything similar.
You may print the output to STDOUT, return it from a function, or anything similar.

Test cases
Your program should solve any of the test cases below in less than a minute.
N        Buddies
2        []
4        []
8        []
15       [53]
16       []
23       [6]
42       [74, 146, 161]
126      [222, 438, 483, 674, 746, 851, 1466, 1631, 1679]
204      [364,548,692,762,782,852,868,1268,1626,2474,2654,2921,2951,3266,3446,3791,4274,4742,5426,5462,6233,6434,6542,7037,8561,14426,14642,15491,15833,22547]

Scoring
This is code-golf, so the shortest answer in bytes wins.

Jelly, 14 bytes
ÆfVṢṚḌ
ÇÇ€=ÇTḟ

Execution time could be halved with DF instead of V, but it still completes the combined test cases in under thirty seconds.
Try it online! or verify all test cases.
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.

I think that Ç€=$ would be a bit faster than Ç€=Ç, given the time constraint.

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.

PowerShell v3+, 450 bytes
param($n)function f{param($a)for($i=2;$a-gt1){if(!($a%$i)){$i;$a/=$i}else{$i++}}}
$y=($x=@((f $n)-split'(.)'-ne''|sort))|?{$_-eq(f $_)}
$a,$b=$x
$a=,$a
while($b){$z,$b=$b;$a=$a+($a+$y|%{$c="$_";0..$c.Length|%{-join($c[0..$_]+$z+$c[++$_..$c.Length])};"$z$c";"$c$z"})|select -u}
$x=-join($x|sort -des)
$l=@();$a|?{$_-eq(f $_)}|%{$j=$_;for($i=0;$i-le$x;$i+=$j){if(0-notin($l|%{$i%$_})){if(-join((f $i)-split'(.)'|sort -des)-eq$x){$i}}}$l+=$j}|?{$_-ne$n}

Finally!
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 --
PS C:\Tools\Scripts\golfing> Measure-Command {.\prime-factors-buddies.ps1 204}

Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 27
Milliseconds      : 114
Ticks             : 271149810
TotalDays         : 0.000313830798611111
TotalHours        : 0.00753193916666667
TotalMinutes      : 0.45191635
TotalSeconds      : 27.114981
TotalMilliseconds : 27114.981

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.
Examples
PS C:\Tools\Scripts\golfing> 2,4,8,15,16,23,42,117,126,204|%{"$_ --> "+(.\prime-factors-buddies $_)}
2 -->
4 -->
8 -->
15 --> 53
16 -->
23 --> 6
42 --> 74 146 161
117 --> 279 939 993 3313 3331
126 --> 222 438 674 746 1466 483 851 1679 1631
204 --> 782 2921 3266 6233 3791 15833 2951 7037 364 868 8561 15491 22547 852 762 1626 692 548 1268 2654 3446 2474 5462 4742 5426 4274 14426 6542 6434 14642

That's the most dollars I've ever seen!

@Fatalize That's only 64 out of 450, which is surprisingly a little on the low side percentage-wise (14.22%) for PowerShell answers.

CJam, 26 23 bytes
{_mfs$:XW%i){mfs$X=},^}

Try it online
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.

05AB1E, 17 bytes
Code:
ÒJ{©RƒNÒJ{®QN¹Ê*–

Explanation:
Ò                  # Get the factorization with duplicates, e.g. [3, 3, 13]
 J                 # Join the array, e.g. 3313
  {©               # Sort and store in ©, e.g. 1333
    R              # Reverse the number, e.g. 3331. This is the upperbound for the range
     ƒ             # For N in range(0, a + 1), do...
      NÒ           # Push the factorization with duplicates for N
        J          # Join the array
         {         # Sort the string
          ®Q       # Check if equal to the string saved in ©
            N¹Ê    # Check if not equal to the input
               *   # Multiply, acts as a logical AND
                –  # If 1, print N

Uses the CP-1252 encoding. Try it online!

Pyth, 17
LSjkPb-fqyTyQSs_y

Test suite.
Uses the same observation as from Martin's post.
Expansion:
LSjkPb        ##  Define a function y(b) to get the sorted string of digits
              ##  of the prime factors of b
    Pb        ##  prime factors
  jk          ##  join to a string with no separator
 S            ##  Sort

-fqyTyQSs_yQQ ##  Auto-fill variables
         _yQ  ##  get reversed value of y(input)
       Ss     ##  convert that string to a list [1 ... y(input)]
 fqyTyQ       ##  keep numbers T from the list that satisfy y(T)==y(input)
-           Q ##  remove the input from the result

JavaScript (ES6), 163 158 bytes
Edit: It has been clarified that a prime such as 23 should return [6] rather an empty result set. Saved 5 bytes by removing a now useless rule that was -- on purpose -- preventing that from happening.
The last test case is commented so that this snippet runs fast enough, although it should complete in less than one minute just as well.

let f =

n=>[...Array(+(l=(p=n=>{for(i=2,m=n,s='';i<=m;n%i?i++:(s+=i,n/=i));return s.split``.sort().reverse().join``})(n))+1)].map((_,i)=>i).filter(i=>i&&i-n&&p(i)==l)

console.log(JSON.stringify(f(2)));
console.log(JSON.stringify(f(4)));
console.log(JSON.stringify(f(8)));
console.log(JSON.stringify(f(15)));
console.log(JSON.stringify(f(16)));
console.log(JSON.stringify(f(23)));
console.log(JSON.stringify(f(42)));
console.log(JSON.stringify(f(126)));
//console.log(JSON.stringify(f(204)));

Powershell, 147 bytes (CodeGolf version)
param($n)filter d{-join($(for($i=2;$_-ge$i*$i){if($_%$i){$i++}else{"$i"
$_/=$i}}if($_-1){"$_"})|% t*y|sort -d)}2..($s=$n|d)|?{$_-$n-and$s-eq($_|d)}

Note: The script solve last test cases less than 3 minutes on my local notebook. See "performance" solution below.
Less golfed test script:
$g = {

param($n)
filter d{                       # in the filter, Powershell automatically declares the parameter as $_
    -join($(                    # this function returns a string with all digits of all prime divisors in descending order
        for($i=2;$_-ge$i*$i){   # find all prime divisors
            if($_%$i){
                $i++
            }else{
                "$i"            # push a divisor to a pipe as a string
                $_/=$i
            }
        }
        if($_-1){
            "$_"                # push a last divisor to pipe if it is not 1
        }
    )|% t*y|sort -d)            # t*y is a shortcut to toCharArray method. It's very slow.
}
2..($s=$n|d)|?{                 # for each number from 2 to number with all digits of all prime divisors in descending order
    $_-$n-and$s-eq($_|d)        # leave only those who have the 'all digits of all prime divisors in descending order' are the same
}

}

@(
    ,(2   ,'')
    ,(4   ,'')
    ,(6   ,23)
    ,(8   ,'')
    ,(15  ,53)
    ,(16  ,'')
    ,(23  ,6)
    ,(42  ,74, 146, 161)
    ,(107 ,701)
    ,(117 ,279, 939, 993, 3313, 3331)
    ,(126 ,222, 438, 483, 674, 746, 851, 1466, 1631, 1679)
    ,(204 ,364,548,692,762,782,852,868,1268,1626,2474,2654,2921,2951,3266,3446,3791,4274,4742,5426,5462,6233,6434,6542,7037,8561,14426,14642,15491,15833,22547)
) | % {
    $n,$expected = $_

    $sw = Measure-Command {
        $result = &$g $n
    }

    $equals=$false-notin(($result|%{$_-in$expected})+($expected|?{$_-is[int]}|%{$_-in$result}))
    "$sw : $equals : $n ---> $result"
}

Output:
00:00:00.0346911 : True : 2 --->
00:00:00.0662627 : True : 4 --->
00:00:00.1164648 : True : 6 ---> 23
00:00:00.6376735 : True : 8 --->
00:00:00.1591527 : True : 15 ---> 53
00:00:03.8886378 : True : 16 --->
00:00:00.0441986 : True : 23 ---> 6
00:00:01.1316642 : True : 42 ---> 74 146 161
00:00:01.0393848 : True : 107 ---> 701
00:00:05.2977238 : True : 117 ---> 279 939 993 3313 3331
00:00:12.1244363 : True : 126 ---> 222 438 483 674 746 851 1466 1631 1679
00:02:50.1292786 : True : 204 ---> 364 548 692 762 782 852 868 1268 1626 2474 2654 2921 2951 3266 3446 3791 4274 4742 5426 5462 6233 6434 6542 7037 8561 14426 14642 15491 15833 22547

Powershell, 215 bytes ("Performance" version)
param($n)$p=@{}
filter d{$k=$_*($_-le3e3)
($p.$k=-join($(for($i=2;!$p.$_-and$_-ge$i*$i){if($_%$i){$i++}else{"$i"
$_/=$i}}if($_-1){($p.$_,"$_")[!$p.$_]})-split'(.)'-ne''|sort -d))}2..($s=$n|d)|?{$_-$n-and$s-eq($_|d)}

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.
Less golfed test script:
$g = {

param($n)
$p=@{}                          # hashtable for 'all digits of all prime divisors in descending order'
filter d{                       # this function returns a string with all digits of all prime divisors in descending order
    $k=$_*($_-le3e3)            # hashtable key: a large hashtable is not effective, therefore a key for numbers great then 3000 is 0
                                # and string '-le3e3' funny
    ($p.$k=-join($(             # store the value to hashtable
        for($i=2;!$p.$_-and$_-ge$i*$i){
            if($_%$i){$i++}else{"$i";$_/=$i}
        }
        if($_-1){
            ($p.$_,"$_")[!$p.$_] # get a string with 'all digits of all prime divisors in descending order' from hashtable if it found
        }
    )-split'(.)'-ne''|sort -d)) # split each digit. The "-split'(.)-ne''" code is faster then '|% t*y' but longer.
}
2..($s=$n|d)|?{                 # for each number from 2 to number with all digits of all prime divisors in descending order
    $_-$n-and$s-eq($_|d)        # leave only those who have the 'all digits of all prime divisors in descending order' are the same
}

}

@(
    ,(2   ,'')
    ,(4   ,'')
    ,(6   ,23)
    ,(8   ,'')
    ,(15  ,53)
    ,(16  ,'')
    ,(23  ,6)
    ,(42  ,74, 146, 161)
    ,(107 ,701)
    ,(117 ,279, 939, 993, 3313, 3331)
    ,(126 ,222, 438, 483, 674, 746, 851, 1466, 1631, 1679)
    ,(204 ,364,548,692,762,782,852,868,1268,1626,2474,2654,2921,2951,3266,3446,3791,4274,4742,5426,5462,6233,6434,6542,7037,8561,14426,14642,15491,15833,22547)
) | % {
    $n,$expected = $_

    $sw = Measure-Command {
        $result = &$g $n
    }

    $equals=$false-notin(($result|%{$_-in$expected})+($expected|?{$_-is[int]}|%{$_-in$result}))
    "$sw : $equals : $n ---> $result"
}

Output:
00:00:00.0183237 : True : 2 --->
00:00:00.0058198 : True : 4 --->
00:00:00.0181185 : True : 6 ---> 23
00:00:00.4389282 : True : 8 --->
00:00:00.0132624 : True : 15 ---> 53
00:00:04.4952714 : True : 16 --->
00:00:00.0128230 : True : 23 ---> 6
00:00:01.4112716 : True : 42 ---> 74 146 161
00:00:01.3676701 : True : 107 ---> 701
00:00:07.1192912 : True : 117 ---> 279 939 993 3313 3331
00:00:07.6578543 : True : 126 ---> 222 438 483 674 746 851 1466 1631 1679
00:00:50.5501853 : True : 204 ---> 364 548 692 762 782 852 868 1268 1626 2474 2654 2921 2951 3266 3446 3791 4274 4742 5426 5462 6233 6434 6542 7037 8561 14426 14642 15491 15833 22547

PHP 486 bytes
could probably be shorter with an algorithm that´s not so by the book.
(but I like the current byte count)
function p($n){for($i=1;$i++<$n;)if($n%$i<1&&($n-$i?p($i)==$i:!$r))for($x=$n;$x%$i<1;$x/=$i)$r.=$i;return $r;}function e($s){if(!$n=strlen($s))yield$s;else foreach(e(substr($s,1))as$p)for($i=$n;$i--;)yield substr($p,0,$i).$s[0].substr($p,$i);}foreach(e(p($n=$argv[1]))as$p)for($m=1<<strlen($p)-1;$m--;){$q="";foreach(str_split($p)as$i=>$c)$q.=$c.($m>>$i&1?"*":"");foreach(split("\*",$q)as$x)if(0===strpos($x,48)|p($x)!=$x)continue 2;eval("\$r[$q]=$q;");}unset($r[$n]);echo join(",",$r);

breakdown
// find and concatenate prime factors
function p($n)
{
    for($i=1;$i++<$n;)  // loop $i from 2 to $n
        if($n%$i<1      // if $n/$i has no remainder
            &&($n-$i    // and ...
                ?p($i)==$i  // $n!=$i: $i is a prime
                :!$r        // $n==$i: result so far is empty ($n is prime)
            )
        )
            for($x=$n;      // set $x to $n
                $x%$i<1;    // while $x/$i has no remainder
                $x/=$i)     // 2. divide $x by $i
                $r.=$i;     // 1. append $i to result
    return $r;
}

// create all permutations of digits
function e($s)
{
    if(!$n=strlen($s))yield$s;else  // if $s is empty, yield it, else:
    foreach(e(substr($s,1))as$p)    // for all permutations of the number w/o first digit
        for($i=$n;$i--;)            // run $i through all positions around the other digits
            // insert removed digit at that position and yield
            yield substr($p,0,$i).$s[0].substr($p,$i);
}

// for each permutation
foreach(e(p($n=$argv[1]))as$p)
    // create all products from these digits: binary loop through between the digits
    for($m=1<<strlen($p)-1;$m--;)
    {
        // and insert "*" for set bits
        $q="";
        foreach(str_split($p)as$i=>$c)$q.=$c.($m>>$i&1?"*":"");
        // test all numbers in the expression
        foreach(split("\*",$q)as$x)
            if(
                0===strpos($x,48)   // if number has a leading zero
                |p($x)!=$x          // or is not prime
            )continue 2; // try next $m
        // evaluate expression and add to results (use key to avoid array_unique)
        eval("\$r[$q]=$q;");
    }

// remove input from results
unset($r[$n]);

// output
#sort($r);
echo join(",",$r);

Actually, 27 bytes
This uses the same algorithm that Martin, Adnan, FryAmTheEggman, and Dennis have been using. Golfing suggestions welcome. Try it online!
`w"i$n"£MΣSR≈`╗╜ƒ;╝R`╜ƒ╛=`░

Ungolfing
          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.

Japt, 18 bytes
k ¬ñ
Ôn õ f@¥Xk ¬ñ

Try it

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes


text:
Is it an Odd Word?
Challenge
Given a single word as input, determine if the word is odd or even.
Odd and Even words
Assume the general rules:
odd + odd = even
even + odd = odd
odd + even = odd
even + even = even

In the alphabet, the odd letters are:
aeiou

And the even letters are:
bcdfghjklmnpqrstvwxyz

The same applies to capital letters (AEIOU are odd and BCDFGHJKLMNPQRSTVWXYZ are even).
You then 'add' each of the letters in the word together. For example, the word cats is equivalent to:
even + odd + even + even

Which simplifies to:
odd + even

Which simplifies further to:
odd

So the word cats is odd.
Examples
Input:  trees
Output: even

Input:  brush
Output: odd

Input:  CAts
Output: odd

Input:  Savoie
Output: even

Input:  rhythm
Output: even

Rules
All input will be a single word which will only contain alphabetical characters.
If the word is odd, output a truthy value. If the word is even, output a falsey value.
Winning
The shortest code in bytes wins.

Could you add an example of a word without any odd letters.

@Hedi I've added one, rhythm

Excuse you. Odd Word™ has been trademarked already by JLee. This is an unauthorized use of the term. :P

This is begging for a pure regex submission

Is the input guaranteed to only contain alphabetical characters?

@DJMcMayhem Whoops, I thought I clarified that :)

The answer is no. Only numbers are odd.

Got a hint for everybody... The ASCII values of the vowels in question are always odd. No doubt someone will exploit that for a few bytes ;).

Is it possible to arrive at the answer by simply knowing the number of odd and even characters (vowels and consonants)?

@RohanJhunjhunwala Nearly 6 years later, and this is finally done.

05AB1E, 6 bytes
lžMÃgÉ

Explanation
l       # convert to lower case
 žMÃg   # count odd letters
     É  # true if odd else false

Try it online!

EXCEL, 79 bytes:
=MOD(SUMPRODUCT(LEN(A1)-LEN(SUBSTITUTE(LOWER(A1),{"a","e","i","o","u"},""))),2)

input:
This function can be placed anywhere EXCEPT A1
Put your word in question into A1.
Output: 0 if even, 1 if odd.

JavaScript (ES6), 34 41 33 32 bytes

Saved 1 bytes thanks to Arnauld:
s=>~s.split(/[aeiou]/i).length&1

Odd word : returns 1
Even words : returns 0

Previous solutions:
33 bytes thanks to Arnauld:
s=>s.split(/[aeiou]/i).length&1^1

Odd word : returns 1
Even words : returns 0

Another way without bitwise operators:
s=>++s.split(/[aeiou]/i).length%2

41 bytes:
(s,a=s.match(/[aeiou]/ig))=>a&&a.length%2

Odd word : returns 1
Even words with odd letters : returns 0
Even words with no odd letters : returns null

42 bytes to return 0 instead of null:
(s,a=s.match(/[aeiou]/ig))=>a?a.length%2:0

34 bytes, breaks on words with no odd letters:
f=s=>s.match(/[aeiou]/ig).length%2

Saved 2 bytes thanks to Shaun H
s=>s.match(/[aeiou]/ig).length%2

This method breaks when word has no vowels. That said: f= isn't needed, and calling exec on the regex object is shorter. s=>/[aeiou]/ig.exec(s).length%2

I don't have the same result with exec with the g flag.

dammit brain yeah ignore that, f= still isn't needed though

Could you do s=>s.split(/[aeiou]/i).length&1^1?

s=>~s.split(/[aeiou]/i).length&1 is actually one byte shorter.

Eww, ++...length%2? I'd have written that ...length%2<1.

@Hedi how does the logic on this work? I'm trying to make sense of this...

@WallyWest the split(...).length is the number of gap between odd letters (may be even letters or empty string). If we just did %2 the result would be falsy for odd words and truthy for even words.
The ~ inverts the bits of its operand (~x == -x-1) so if x was even ~x is odd.  The &1 does the same as %2 (except that negative value %2 gives -0 or -1).

The expected result is If the word is odd, output a truthy value. So returning zero for odd words won't do because 0 is a falsy value.

Didn't read the end of question, sorry :)

C, 42 bytes
f(char*s){return*s&&2130466>>*s&1^f(s+1);}

This works with GCC 4.x on a x86-64 CPU. Results may vary with different setups.
Test it on repl.it.
At the cost of 5 more bytes, undefined behavior can be avoided, so the code should work as long as ints are at least 32 bits wide.
f(char*s){return*s&&2130466>>(*s&31)&1^f(s+1);}

How it works
Modulo 32, the character codes of all odd letters are 1, 5, 9, 15, and 21. 2130466 is the 32-bit integer that has set bits at these positions and unset bits at all others.
When f is called on a string, it first checks if the first character of the string is a null byte (string terminator). If it is, *s yields 0 and f returns 0. Otherwise, *s yield the character code of a letter  and the right argument of the logical AND (&&) is executed.
For >>, GCC generates a shift instruction. On a x86-64 CPU, the corresponding instruction for a 32-bit integer ignores all but the lower 5 bits of the right argument, which avoids reducing *s modulo 32. The right shift and the following bitwise AND with 1 extracts the bit of 2130466 that corresponds to the letter, which will be 1 if and only if the letter is odd.
Afterwards, we increment the pointer s (effectively discarding the first letter), call f recursively on the beheaded string, and take the bitwise XOR of the result from above and the result of the recursive call.

Great bit wise work!

erees Return 0 in Ideone, is it right?

@RosLuP No, that's not correct. It works on my computer and on repl.it though (possibly because the version of GCC is quite different).

Yeah, it's definitely the compiler. With clang 3.7, it works on Ideone as well.

Brain-Flak 206 196 192 178 + 3 = 181 bytes
Try it Online!
([]<{({}[((((((()()())){}){}){}){}){}()]){({}[({}())]){({}[({})]){({}[({}()())]){({}[({})]){({}<>)(<>)}}}}}{}{}}><>[[]]<>()()){(({}[<>(())<>()()])){{}({}())((<>)<>)}{}}{}<>({}<>)

This requires the -c flag to run in ASCII mode adding an extra 3 bytes to the length of the program.
Ungolfed
([]<
{({}[(((((()()()){}){}){}){}){}()])
 {
  ({}[()()()()])
  {
   ({}[()()()()])
   {
    ({}[(()()()){}])
    {
     ({}[(()()()){}])
     {
      ({}<>)
      (<>)
     }
    }
   }
  }
 }
 {}
}
><>[[]]<>)
(<(()()<>)>)<>{({}[()])<>(({}()[({})])){{}(<({}({}))>)}{}<>}{}<>({}<{}><>)

Explanation
First store the stack height for future purposes
([]<...>

Then while the stack is not empty (assumes that none of the characters is zero)
{...}

Subtract ninety seven (and store 3 for later optimizations)
({}[((((((()()())){}){}){}){}){}()])

If it is not zero (i.e. not a)
{...}

Subtract 4 (and store 4 for later optimizations)
({}[({}())])

If it is not zero (i.e. not e)
{...}

Subtract 4 (and store 4 for later optimizations)
({}[({})])

If it is not zero (i.e. not i)
{...}

Subtract 6 (and store 6 for later optimizations)
({}[({}()())])

If it is not zero (i.e. not o)
{...}

Subtract 6 (store 6 because the program expects one later)
({}[({})])

If it is not zero (i.e. not u)
{...}

Move the remainder to the other stack and put a zero on the active stack to escape all of the ifs
({}<>)(<>)

Once all of the ifs have been escaped remove the zero and the six
{}{}

Once all the characters have been processed subtract the height of the offset from the originally stored height.
...<>[[]]<>)

Mod by two
{(({}[<>(())<>()()])){{}({}())((<>)<>)}{}}{}<>({}<>)

I think -c is only +1 byte since ever Perl answer also only adds 1 byte / flag.

@ThreeFx That's because perl -pe'code' is only one byte longer than perl -e'code'.

Python, 41 bytes
lambda s:sum(map(s.count,"aeiouAEIOU"))%2

sed 44 (42 + 1 for -n) 43
-1 thanks to Neil
s/[aeiou][^aeiou]*[aeiou]//gi
/[aeiou]/Ico

Prints o for odd and nothing for even

s/[aeiou][^aeiou]*[aeiou]//gi might save you a byte, if I've counted correctly.

@Neil Yep! I wish sed could do non-greedy search.

Jelly, 13 12 11 bytes
-1 byte thanks to @Luis Mendo (use Ḃ to replace %2)
-1 byte thanks to @Dennis (use a string compression)
Œlf“¡ẎṢɱ»LḂ

All test cases are at TryItOnline
How?
Œlf“¡ẎṢɱ»LḂ - Main link takes an argument - s
Œl          - lowercase(s)
   “¡ẎṢɱ»   - string of lowercase vowels (compression using the words a and eoui)
  f         - filter - keep only the vowels
         L  - length - the number of vowels
          Ḃ - Bit (modulo 2)

Non-competing, 5 bytes (since I just added the function Øc)
fØcLḂ

Test cases also at TryItOnline
Same as above, but Øc yields the Latin alphabet's vowels, 'AEIOUaeiou'

I think you can replace %2 by Ḃ

euoi is a cry of impassioned rapture in ancient Bacchic revels, so you can use the dictionary and get the vowels as “¡ẎṢɱ».

@Dennis - LOL of course!

@Dennis How exactly does that work? Is it just base-compression to get the index of a word in a giant dictionary? Where does the 'a' come from?

@DJMcMayhem it's a base 250 compression using a dictionary (which I believe was just taken from Dennis's computer) with separation between short (less than 6 char) and long words. Some code to automate the process of making compressed strings was written by Lynn. The unused 6 bytes are Jelly's string identifying characters “”«»‘’ (there is also ⁾ which is for a two-char string, but that is used within compressed strings).

Brain-Flak, 524, 446, 422 bytes
{(<((((()()()()){}){}){}<>)>)<>{({}[()])<>(({}[({})]())){{}(<({}({}))>)}{}<>}{}<>([(((({}<{}<>>))))]()){(<{}>)<>({}[()])<>}<>({}())<>{}([{}]()()()()()){(<{}>)<>({}[()])<>}<>({}())<>{}(((()()())){}{}[{}]){(<{}>)<>({}[()])<>}<>({}())<>{}(((()()()()())){}{}[{}]){(<{}>)<>({}[()])<>}<>({}())<>{}((((()()()){}())){}{}[{}]){(<{}>)<>({}[()])<>}<>({}())<>{}}(<(()())>)<>{({}[()])<>(({}[({})]())){{}(<({}({}))>)}{}<>}{}<>({}<{}<>>)

Try it online!
Ungolfed, more readable version:
{((((()()()()){}){}){})(<({}<>)>)<>{({}[()])<>(({}()[({})])){{}(<({}({}))>)}{}<>}{}<>({}<{}><>)((((({})))))
(())
({}[{}]){(<{}>)<>({}[()])<>}<>({}())<>{}
(()()()()())
({}[{}]){(<{}>)<>({}[()])<>}<>({}())<>{}
(()()()()()()()()())
({}[{}]){(<{}>)<>({}[()])<>}<>({}())<>{}
(()()()()()()()()()()()()()()())
({}[{}]){(<{}>)<>({}[()])<>}<>({}())<>{}
(()()()()()()()()()()()()()()()()()()()()())
({}[{}])
{(<{}>)<>({}[()])<>}<>({}())<>{}}<>(()())(<({}<>)>)<>{({}[()])<>(({}()[({})])){{}(<({}({}))>)}{}<>}{}<>({}<{}><>){{}([()])
(<><>)}({}{}())

The Ungolfed version doesn't seem to work (can't fit TIO link in comment ;_;)

"more readable" 'nough said

Python, 42 bytes
lambda s:sum(c in"aeiouAEIOU"for c in s)%2

Not a whole lot to explain here. An unnamed function that returns 0 or 1.

Haskell, 38 37 bytes
odd.length.filter(`elem`"aeiouAEIOU")

Thanks to Angs for one byte!

Truthy for odd, so you have to use odd instead of even. Saves one byte!

@Angs clever :)

Python 3, 53 Bytes
This can probably be golfed further:
lambda n:[x in 'aeiou' for x in n.lower()].count(1)&1

Remove spaces between in and 'aeiou' and for, and use sum to save 8 bytes: lambda n:sum(x in'aeiou'for x in n.lower())&1 (although as you can see from DJMcMayhem's post using all ten vowels is also shorter)

Thanks for the tips! I noticed the extra spaces a little bit after posting, but in all honesty, @DJMcMayhem and I had identical approaches with his being the best version I can imagine for a Python solution. I didn't know about the sum() command before this golf so once again I learned something! Have a nice day :)

C 52 bytes
h(o){o=strpbrk(o,"aeiouAEIOU");return o?1^h(o+1):0;}

the main and the result:
main()
{int   k;
 char *a[]={"trees","brush","CAts","Savoie","rhythm", 0};

 for(k=0;a[k];++k)
     printf("[%s]=%s\n", a[k], h(a[k])?"odd":"even");
}

/*
91
[trees]=even
[brush]=odd
[CAts]=odd
[Savoie]=even
[rhythm]=even

*/

i try to use int as pointers but it not compile where the use of inirection *... the solution printed first here was wrong...

h(o){return~-o?1^h(1+strpbrk(o,"aeiouAEIOU")):1;} saves 3 bytes.

s;h(o){s=~-o?1^h(1+strpbrk(o,"aeiouAEIOU")):1;}  the result is in the global variable s...

Unfortunately, that's not allowed. Functions have to be reusable, and this will break if you use it more than once. Also, saving the output in a variable is not allowed, unless you take the location as user input.

I think in this case reuse is possible becausr the start value of s now is not important...ok ok now i think something can go wrong... Thanks

Unfortunately, storing the output in a variable is not considered a valid form of output. The code I proposed is exactly as long as yours and complies with our rules for I/O.

Java, 73
boolean f(String s){return s.replaceAll("(?i)[^aeiou]","").length()%2>0;}

saw a couple other java answers, otherwise wouldn't have shared. Thanks to Phaeze for saving a byte.

I think you can save a byte with %2>0

Pyth, 14 bytes
%l@"aeiou"rQ02

Try it Online!
Explanation:
  @"aeiou"       Grab only the vowels
          rQ0      From lowercased input
 l                 Get the length of this
%            2     And mod 2 to check for oddness

Ruby, 30 bytes
->w{w.scan(/[aeiou]/i).size%2}

Vim, 32, 31, 29 keystrokes
:s/[^aeiou]//gi
C<C-r>=len(@")%2<cr>

Since the V interpreter is backwards compatible, you can try it online! right here.
One Three bytes saved thanks to m-chrzan!

Can you do s/.../gi instead of s/\c.../g?

@m-chrzan Woah, awesome tip. Thanks!

Also, '<C-r>"' -> @".

@m-chrzan Wow, thanks. You should consider posting on the vim tips thread. I bet you'd have some useful ones.

I found out about @" 15 minutes ago. The best vim tip I have is to use :help foo and / the documentation :P.

Well, since we're talking about golf, :h foo is shorter. :P

dimwit, 14 bytes (non-competing)
ar[aeiou]}et}T

I thought this would be a fun, simple challenge to start with for a new language.
Explanation

a -  push a new array to the matrix
r[aeiou]} - count occurrences of all values matching the regex "[aeiou]" in the first array (since the first array contains the input), ignoring case, and push that value to the end of the last array.
e - if the last number in the last array is even (which we set to the number of occurrences), perform the next operations up until a closing bracket ("}")
t - stop execution, clear the matrix, and set the first value to be false
} - end of e code block
T - stop execution, clear the matrix, and set the first value to be true

Try it online!
Use the Input field to enter the word.
I'll soon add documentation...

Bash, 36 bytes
x=${1,,//[aeiou]/}
((1&${#1}&${#x}))

Try it online!
Zsh, 30 bytes
((1&$#1&${#${1:l}//[aeiou]/}))

Try it online!
Accepts input as its first argument. Exits with nonzero if even, exits zero if odd.
We barely beat out the bash+coreutils solution!
x=${1,,//[aeiou]/}  # lowercase first argument, then remove all [aeiou]
((1&${#1}&${#x}))
  1&     &          # bitwise-and 1 with
    ${#1} ${#x}     # length of first parameter and length of stripped parameter
((             ))   # if nonzero, exit 0 (truthy in shell)

The Zsh solution is very similar, but uses the ability to nest parameter expansions to save an assignment.

K (ngn/k), 13 bytes
=/^"aeiou"?_:

Try it online!
Returns 1 for "even" inputs and 0 for "odd" ones.

_: lowercase the (implicit) input
^"aeiou"? generate a bitmask indicating which characters in the (lowercased) input are not vowels
=/ do an equals-reduce; if there are an even number of 0s (i.e. vowels), this returns 1. if there are an odd number, it returns 0

By the default site I/O rules, 1 for even and 0 for odd should be allowed.

Great, thanks! Updated the answer to trim those notes out.

J, 20 bytes
2|+/@e.&'aeiouAEOIU'

Straight-forward approach
Explanation
2|+/@e.&'aeiouAEOIU'  Input: string S
     e.&'aeiouAEOIU'  Test each char in S for membership in 'aeiouAEOIU'
  +/@                 Sum those values
2|                    Take it modulo 2 and return

Haha, I just posted a J answer (now deleted) 1 byte longer than this. Nice job!

Where is the command for "take input"?

@RosLuP This is a verb (function) that takes a single argument as input. J uses tacit programming so commands are chained together and pass values implicitly

C# 64 62 56 50 Bytes
s=>1>s.Split("aeiouAEIOU".ToCharArray()).Length%2;

We are already using linq, so Contains saves 2 bytes over IndexOf
Using the method overload of Count saves 6 bytes
Thanks to @Milk for suggesting a neat method and saving 6 more bytes

An anonymous function that takes a string and counts the odd letters then returns true if there is an odd number of them or false if there is not.
This new solution splits the string on any of the characters in the given char array. The mechanics of this flip the meaning of the %2 result; 0 is now odd and 1 even hence the 1>.
Try it online here!

It's only 50 bytes to use string.Split() to count the vowels and you don't need LINQ. s=>1>s.Split("aeiouAEIOU".ToCharArray()).Length%2;

@milk Thanks for that, very neat solution.

Japt, 7 bytes
1&Uè"%v

Test it online! Outputs 1 for odd, 0 for even.
How it works
         // Implicit: U = input string
  Uè     // Count the number of matches of the following regex in the input:
    "%v  //   /[AEIOUaeiou]/g
1&       // Take only the first bit (convert 1, 3, 5, etc. to 1, and others to 0)
         // Implicit output

PHP, 41 bytes
<?=count(spliti("[aeiou]",$argv[1]))%2-1;

This outputs -1 for truthy and 0 for falsey.

spliti was deprecated in PHP 5.3.0 (30 June 2009), and removed in PHP 7.0.0 (03 Dec 2015), so this submission should have specified a version for the language, e.g. "PHP 5.6.26". This submission would not have even worked in "PHP 5.2.17", the last version that didn't print a deprecation warning, because the <?= shorthand for <?php echo  was only introduced in PHP 5.4.0.

Mathematica, 44 bytes
OddQ@StringCount[#,Characters@"aeiouAEIOU"]&

Gives True for an odd string and False for an even one.

+1 to any man or woman learning mathematica

Retina, 19 bytes
Mi`[aeiou]
[13579]$

Try it online! (The first line enables a linefeed-separated test suite.)
The first line counts the vowels in the input. The second line checks that the result is odd.

PowerShell v2+, 45 42 bytes
($args[0]-replace'[^aeiouAEIOU]').Length%2

Takes input $args[0], sends it through -replace to remove all non-vowel characters, takes the resulting .length, and %2 to check whether it's odd/even.
Examples
PS C:\Tools\Scripts\golfing> 'trees','brush','CAts','Savoie','rhythm'|%{"$_ --> "+(.\is-it-an-odd-word.ps1 $_)}
trees --> 0
brush --> 1
CAts --> 1
Savoie --> 0
rhythm --> 0

You can just use [^aeiou] for 37 bytes, as -replace is by default case insensitive. You'd have to use (?-i)[^aeiou] to make it case sensitive.

Octave, 34 bytes
@(s)mod(nnz(~(s'-'aeiouAEIOU')),2)

s'-'aeiouAEIOU'    % Creates a 2D-matrix where each of the odd letters are
                   % subtracted from the string s
~(s'-'aeiouAEIOU') % Negates that array, so the all zero elements become 1
nnz( .... )        % Counts all the non-zero elements (the odd letters)
mod(nnz( ....),2   % Takes this sum modulus 2

This is 6 bytes shorter than the traditional approach using ismember, @(s)mod(sum(ismember(s,'aeiouAEIOU')),2), and two bytes shorter than the regex approach: @(s)mod(nnz(regexpi(s,'[aeiou]')),2).
Test it here.

Java 7, 88
boolean f(char[]s){int x=0;for(char c:s)if("aeiouAEIOU".indexOf(c)>=0)++x;return x%2>0;}

Ungolfed:
  boolean f(char[] s) {
    int x = 0;
    for (char c : s) {
      if ("aeiouAEIOU".indexOf(c) >= 0) {
        ++x;
      }
    }
    return x % 2 > 0;
  }

q, 29 bytes
{mod[sum x in "aeiouAEIOU";2]}

Japt v2.0a0, 5 bytes
Outputs 1 for odd and 0 for even.
è\v u

Try it (Includes all test cases)
è\v u     :Implicit input of string
è         :Count the occurrences of
 \v       :  RegEx /[aeiou]/gi
    u     :Modulo 2

Brachylog, 11 9 bytes
ḷ{∈Ṿ}ˢḍz₂

Try it online!
The predicate fails if the input is odd and succeeds if it is even.
ḷ{  }ˢ       For each lowercased letter of the input,
   Ṿ         map it to the string of lowercase vowels
  ∈          if it's an element of it
     ˢ       and delete it otherwise.
      ḍ      Split the list in half.
       z₂    Are the halves the same length?

Java (JDK), 53 52 51 42 bytes
s->(s+"#").split("(?i)[AEIOU]").length%2<1

Try it online!
Edit: Saved a byte 2 bytes thanks to @JonathanFrech
Edit: Saved another 9 bytes thanks to @Deadcode

return 1>(... to return(...<1 possibly?

Also, could you not use (?i)[aeiou] instead of [aeiouAEIOU]?

You can drop 9 bytes by using a shorthand syntax for returning a single expression.

Vyxal, 3 bytes
A∑∷

Try it Online!

C# 36 Bytes
s=>s.Count("aeiouAEIOU".Contains)%2;

Returns 1 for odd, 0 for even.
Try it online here!

CJam, 18 17 bytes
0lel"aeiou"f{&,^}

Try it online!
Explanation
0                 e# Push 0
 l                e# Read line from input
  el              e# Convert to lowercase
   "aeiou"        e# Push this string
          f{   }  e# Map code block to each char of the input and the string "aeiou"
            &     e# Set intersection of each input char with the "aeiou". The result
                  e# is either that char or the empty string
             ,    e# Length. Gives 0 or 1
              ^   e# Binary XOR. Uses the initial 0 the first time
                  e# Implicitly display

lel_"aeiou"--,1& saves a byte.

@Dennis Thanks! That's very clever. But it's a significantly different approach, you should post it yourself

R, 164 bytes
I'm sure this can be done better, but it's still good practice.
f<-function(w){
l<-"aeiouAEIOU"
c<-0
for(i in 1:10){
for(j in 1:nchar(w)){
if(substr(l,i,i)==substr(w,j,j)){c<-c+1}}}
if(c%%2==0){print("F")}else{print("T")}}

input/output
> f("trees")
[1] "F"
> f("brush")
[1] "T"
> f("CAts")
[1] "T"
> f("Savoie")
[1] "F"
> f("rhythm")
[1] "F"

"F" for false and "T" for true.

Welcome to codegolf fellow R-user. May I recommend the following approach rather to reduce it to 117 bytes: function(w){a=substr;l="aeiouAEIOU";c=0;for(i in 1:10){for(j in 1:nchar(w))if(a(l,i,i)==a(w,j,j))c=c+1};cat(c%%2!=0)}. In other words, use = for assignment rather than <-, removed some unnessecary {...} as well, aliasing the substr() function to a since you use it twice. Finally instead of printing out a T or F string, just print the logical equivalents instead with the cat() function rather than print.

Also, I would recommend to check out my vectorized solution here. There I also use readline() rather than defining a full function which is shorter when only one input is required.

Thanks so much, I will look at all of your suggestions Billywob.

Bash + coreutils, 37 bytes
bc<<<!`sed s:[^aeiou]::ig\;q|wc -m`%2

The input word is taken from STDIN. Output is 1 if the word is odd, or 0 if it is even.
Explanation:
       sed s:[^aeiou]::ig\;q     # remove even letters from input and exit sed
       |wc -m                    # count remaining chars (odd letters + 1 for \n)
bc<<<!`                     `%2  # apply mod 2 and invert the boolean result

Run example:
me@LCARS:/PPCG$ ./odd_word.sh
trees
0

PHP, 43 Bytes
<?=preg_match_all("#[aeiou]#i",$argv[1])%2;

Following the rules directly, just preg_match_all("#[aeiou]#i",$argv[1])%2 qualifies.

Batch, 132 bytes
@echo off
set/ps=
set s=%s%%s:a=%%s:e=%%s:i=%%s:o=%%s:u=%
:l
if "%s%"=="" exit/b0
if "%s:~1%"=="" exit/b1
set s=%s:~2%
goto l

Takes input on STDIN, exits with ERRORLEVEL equal to 1 if the word is odd, 0 if it is even. Works by multiplying all the vowels by five and other letters by six, then calculating the parity of the resulting length.

Turtlèd, 91 65 64 52 47 67 bytes
More bytes because now takes case insensitive input
Changed approach again
does * for even, else o for odd
(trailing space)
!-u[*+.(a,)(e,)(i,)(o,)(u,)(A,)(E,)(I,)(O,)(U,)(*d(*'ou)(o'*u))_]'

It goes through input, writing it down on one square, each time there is a vowel, it moves down, flips the state of a the output cell, continues until EOF of input, then removes the cell where it writes down all the characters.

Lua, 47 44 43 Bytes
print(#arg[2]:gsub('[^aeiouAEIOU]','')%2>0)

Takes the input via the command line, replaces all non-vowels with nothing, (removes them), prints true if the length of that is odd, false otherwise.
Old submission
_,n=arg[2]:gsub('[aeiouAEIOU]','')print(n%2~=0)

Go, 93 bytes
func(s string)int{n:=0;for _,c:=range s{for _,d:=range"aeiouAEIOU"{if c==d{n++}}};return n%2}

Try it online! Note: The return value is 0 for even and 1 for odd, which isn't directly usable as a boolean in Go, and must be compared against zero. It would take +2 bytes to return boolean.

R, 78 bytes
Solution is based on counting the number of vowels:
s=strsplit;w=s(readline(),"")[[1]];v=s("aeiouAEIOU","")[[1]];sum(w%in%v)%%2!=0

Explanation
Unfortunately most functions in R relating to strings work on vectors of characters rather than full strings, thus the solution converts input into a vector using strsplit and checks whether this contains any vowels => sum the number of vowels and check if odd/even.
Also I found that using v=s("aeiouAEIOU","")[[1]] was shorter than manually inputting a vector of vowels which would have worked if only lower or upper case letters were used.

R, 49 bytes
f=function(x)nchar(gsub("[^aeiou]","",x,i=T))%%2==0

Examples:
> f("cats")
[1] FALSE

> f("Savoie")
[1] TRUE

If it doesn't need a function and I can assume x is the input:
36 bytes:
!nchar(gsub("[^aeiou]","",x,i=T))%%2

If I can allow an output of 0 for even and 1 for odd:
35 bytes:
nchar(gsub("[^aeiou]","",x,i=T))%%2

Explanation
I'm substituting all vowels with blank character, ignoring case (i=T). This works because the i is enough to unambigiously identify the ignore.case argument and T is short for TRUE. Then count the odd characters and see if there's a remainder. If a number isn't a good response, I use ! (not) to coerce the 0/1 to TRUE/FALSE.

Your primary answer is reversed (the question states that odd=truthy), but even that way with coercion it could be %%2<1. And i=T can be changed to 1. Without coercion this yields 44 bytes, or 42 bytes using pryr, or 37 bytes using R v4.1.0.

T-SQL (SQL Server 2014), 217 bytes
Golfed
declare @ table(a char)declare @i int=1while @i<=len(@a)begin insert into @ values(SUBSTRING(@a,@i,1))set @i=@i+1 end select count(*)%2from @ where a in('a','e','i','o','u')

Usage
First declare the variable @a as a char of some sort and assign the input like so
declare @a varchar(max) = 'CAts'

Output will either be 1 for odd, or 0 for even
Ungolfed
declare @input varchar(max) = 'rhythm'

declare @temp table ( letter char(1) ) -- table to hold each letter of the word

declare @i int = 1

while @i <= len(@input) -- split each letter, and each row in @temp will have one letter
begin
    insert into @temp values (SUBSTRING(@input, @i, 1))
    set @i = @i + 1
end

-- count the vowels and mod two to get if there's an even number of vowels or an odd number
select count(*) % 2
from @temp
where letter in ('a', 'e', 'i', 'o', 'u') -- use sql's case insensitive strings

Groovy (39 Bytes)
{s->s.collect{/aeiou/=~it?1:0}.sum()%2}

https://groovyconsole.appspot.com/script/5195711326978048

MATL, 8, 7 bytes
13Y2mso

Try it online!
Explanation:
13Y2    % Push the string 'aeiouAEIOU', a predefined literal.
    m   % For each char of the input that is in that string, push a one. For every other element, push a zero.
     s  % Sum this array
      o % Mod 2

Pyke, 10 bytes
l1~Vm/s 2%

Try it here!

Actually, 17 bytes
Golfing suggestions welcome. Try it online!
ù╝"aeiou"`╛c`MΣ1&

Ungolfing
                    Implicit input s.
ù╝                  Add s.lower() to register 1.
  "aeiou"`  `M      Push the string "aeiou" and map the following function over it.
          ╛         Push register 1 to stack.
           c        Count the occurrences of "a", then "e", etc.
              Σ     Sum the counts of these occurrences.
               1&   x&1 == x%2.
                    Implicit return.

You don't have to output the actual words even and odd. Anything that is false and true in your language qualifies

Ah. Thanks @TonHospel. I had not reread the specification since I first saw in chat. Will edit my answer shortly

Perl, 18/19 bytes
Includes +1 for -p
Give input on STDIN, prints 0 for even, 1 for odd
#!/usr/bin/perl -p
$_=1&lc=~y;aeiou;

Must be put in a file, but the file must not have a final newline giving 18 bytes. This is admittedly abusing the perl counting rules a bit since this actually doesn't work when run in a -e commandline which implicitely adds a final \n which makes the program not work. So more honest but 19 bytes is:
#!/usr/bin/perl -p
$_=1&lc=~y;aeiou;;

Julia, 53 Bytes
f(s)=sum(map(x->x in ["aeiouAEIOU"...]?1:2,[s...]))%2

replace odd characters with 1 and even characters with 2, then sum up. if the sum is even, then the word is even.

O, 27 bytes
Q_e\'a-'e-'i-'o-'u-e\;-e01?

PHP, 91 bytes
foreach(str_split($argv[1])as$c)$n+=substr_count("AEIOU",strtoupper($c));if($n%2==0)echo 1;

Outputs 1 for even word, empty for odd word.
Test online
Testing code:
$wa = array('trees','brush','CAts','Savoie','rhythm');
foreach ($wa as $w) {
    $n = 0;
    foreach(str_split($w) as $c)
        $n+=substr_count("AEIOU",strtoupper($c));
    if ($n%2==0) echo 1;
}

Test online

Racket 127 bytes
(if(= 0(modulo(for/sum((i(map(λ(i)(ormap(λ(x)(equal? i x))(string->list"aieouAEIOU")))(string->list s))))(if i 1 0))2))#f #t)

Ungolfed:
(define(f s)
  (let* ((vl (string->list "aieouAEIOU"))
         (od (λ(i) (ormap (λ (x) (equal? i x)) vl)))
         (ol (map od (string->list s)))
         (s (count (λ(i) i) ol ))
         (m (modulo s 2)))
    (if (= m 0) "even" "odd")
  ))

A longer (240 bytes) but more direct version:
(let*((vl(string->list"aieouAEIOU"))(od(λ(i)(ormap(λ(x)(equal? i x))vl))))(let lp((l(string->list s))
(st #t)(d 0))(cond((null? l)(if d"odd""even"))(st(lp(cdr l)#f(if(od(car l))#t #f)))
(else(lp(cdr l)#f(if(equal? d(od(car l)))#f #t))))))

Ungolfed:
(define (f s)
  (let* ((vl (string->list "aieouAEIOU"))
         (od (λ (i) (ormap (λ (x) (equal? i x)) vl) )))
    (let loop ((l (string->list s))
               (starting #t)
               (odd 0))
      (cond
        ((null? l)
         (if odd "odd" "even"))
        (starting
         (loop (rest l) #f
               (if(od (first l))
                  #t #f )))
        (else
         (loop (rest l) #f
               (if (equal? odd
                           (od (first l)))
                   #f #t)))))))

Testing:
(f "trees")
(f "brush")
(f "CAts")
(f "Savoie")
(f "rhythm")

Output:
"even"
"odd"
"odd"
"even"
"even"

Try it online!

Very nice page for online evaluation of Racket code. Its a pity that Racket has not picked up in popularity.

Ruby, 30 bytes
->w{w.count('aeiouAEIOU')%2>0}

Returns true for an odd word and false for an even word. The existing Ruby solution returns 0 for even words, which is a truthy value in Ruby.

Try it online!

Elixir, 45 bytes
&rem(length(Regex.scan(~r/[aeiou]/i,&1)),2)>0

Anonymous function defined using the capture operator. If the number of vowels is odd, the specified word is odd, so the function returns true.
Full program with test cases:
s=&rem(length(Regex.scan(~r/[aeiou]/i,&1)),2)>0
# test cases
IO.puts s.("trees") # false
IO.puts s.("brush") # true
IO.puts s.("CAts")  # true
IO.puts s.("Savoie")    # false
IO.puts s.("rhythm")    # false

Try it online on ElixirPlayground !

Python 2, 41 bytes
lambda s:sum(map(s.count,"aAeEiIoOuU"))%2

Try it online!
Returns 0 for even, and 1 for odd.
Explanation:
Counts how many total odd letters are in the word, and returns whether that number is even (0) or odd (1).

Pip, 9 bytes
-XV Na%:2

Try it online!
 XV        Regex matching [aeiou]
-          Case-insensitive
    N      Count matches in
     a     Command-line argument
      %:2  Mod 2 (the : helps with parsing)

Clojure, 38 bytes
#(rem(count(re-seq #"(?i)[aeiou]"%))2)

Try it online!
This anonymous function outputs 1 for odd and 0 for even.
Explanation
#"(?i)[aeiou]" ; This is a regular expression that matches a capital or lowercase vowel.
re-seq ; Returns a lazy sequence that contains all of the regex's matches from the input string.
count ; Returns the length of that sequence.
rem ; Returns the remainder when that length is divided by 2

Kotlin, 32 bytes
0 is false, 1 is true.
{it.count{it in "aAeEiIoOuU"}%2}

Try it online!

Z80Golf, 34 bytes
0000                restart:
0000   cd 03 80               call   $8003
0003   30 05                  jr   nc,letter
0005                done:
0005   78                     ld   a,b
0006   e6 01                  and   1
0008   ff                     rst   $38
0009   76                     halt
000a                letter:
000a   e6 1f                  and   $1f
000c   3d                     dec   a
000d   28 10                  jr   z,vowel
000f   d6 04                  sub   4
0011   28 0c                  jr   z,vowel
0013   d6 04                  sub   4
0015   28 08                  jr   z,vowel
0017   d6 06                  sub   6
0019   28 04                  jr   z,vowel
001b   d6 06                  sub   6
001d   20 e1                  jr   nz,restart
001f                vowel:
001f   04                     inc   b
0020   18 de                  jr   restart

Try it online!

><>, 47 bytes
0i1+48*%:?v~2%n>~!
26a28*2b* \
r&:{=&+r  >l3(?v

Try it online!

Factor, 34 bytes
[ [ "aeiouAEIOU"in? ] count odd? ]

Try it online!

Regex (Perl / PCRE / Boost / Pythonregex) + /i flag, 24 bytes
^((.*?[aeiou]){2})*+(?2)

Returns a match if odd; returns no match if even.
Try it online! - Perl
Try it online! - PCRE
Try it online! - Boost
Try it online! - Python import regex
Explanation:
^ - Anchor to the beginning of the string
Each (.*?[aeiou]){2} matches the first two "odd" characters it finds, consuming them as it goes. The (...)*+ wrapping it causes this to consume as many pairs as it can (minimum zero), where the + makes it a possessive quantifier, holding onto the first complete match (disabling backtracking).
At this point, the maximum even number of "odd" characters has been consumed, and if the word is "odd", exactly one "odd" character will remain, otherwise none will. (?2) attempts to match one more "odd" character, calling (.*?[aeiou]) (group 2) as a subroutine.
Regex (Ruby / PCRE) + /i flag, 25 bytes
^((.*?[aeiou]){2})*+\g<2>

Try it online! - Ruby
Try it online! - PCRE
This is a port of the Perl/PCRE/Boost regex to Ruby's style of subroutine call. This syntax is also supported by PCRE.
Regex (Java or better) + /i flag, 29 bytes
^((.*?[aeiou]){2})*+.*[aeiou]

Try it online!
This is a port of the regex to flavors that have no subroutine calls, but do have possessive quantifiers.
Regex (.NET or better) + /i flag, 32 bytes
^(?>((.*?[aeiou]){2})*).*[aeiou]

Try it online!
This is a port of the regex to flavors that have no subroutine calls or possessive quantifiers, so the clause (...)*+ has been changed to (?>(...)*) to replace a possessive quantifier with an atomic group.
Regex (ECMAScript or better) + /i flag, 36 bytes
^(?=(((.*?[aeiou]){2})*))\1.*[aeiou]

Try it online! - ECMAScript
Try it online! - Python
This is a port of the regex to flavors that have no subroutine calls, atomic groups, or possessive quantifiers, so the clause (...)*+ has been changed to (?=((...)*))\1 to replace a possessive quantifier with an emulation of an atomic group (using an atomic lookahead, group capture, and backreference).
Regex (POSIX ERE or better) + /i flag, 51 bytes
^(([^aeiou]*[aeiou]){2})*[^aeiou]*[aeiou][^aeiou]*$

Try it online!
This is a port of the regex to flavors that have no subroutine calls and no way to disable backtracking.

Zsh, 28 bytes
<<<$[${#1//[^aeiouAEIOU]}%2]
Attempt This Online!

Kotlin, 39 bytes
{it.count{"aeiouAEIOU".contains(it)}%2}

Try it online!

Arturo, 33 bytes
$=>[%match.count&"[aeiouAEIOU]"2]

Try it
Returns 0 for even, 1 for odd.

excel, 76 bytes
=MOD(SUM(--(MID(A1,ROW(INDIRECT("1:"&LEN(A1))),1)={"a","e","i","o","u"})),2)

put the input in cell A1 and put the output formula in whichever other cell u want
returns 0 for even and 1 for odd
excel equates upper case and lower case letters when doing a direct comparison or something idk i just started using it for work and i'm still figuring it out

Welcome to Code Golf, and nice answer!

@RydwolfPrograms thank u :)

Consider using the sequence function in place of row(indirect("1:"&...)). this gets your solution down to 66 bytes =Mod(Sum(--(Mid(A1,Sequence(Len(A1)),1)={"a","e","I","o","u"})),2)

@TaylorAlexRaine the sequence function came out after this challenge was posted didn't it? that's why i didn't use it. if it actually came out before then i'll modify my answer but i just didn't want to cheat :)

Retina, 24 21 bytes
i`[aeiou]
1
T`Ll`
11

(there's a mandatory additional empty line, but formatting ignores it)
Returns 1 for odd words, and void for even ones.
Try it online!

Java, 59 bytes
s->s.chars().map(c->"aeiouAEIOU".indexOf(c)<0?0:1).sum()%2;

Ungolfed test program
public static void main( String[] args )
{
    Function<String, Integer> func = s -> s.chars().map( c -> "aeiouAEIOU".indexOf( c ) < 0 ? 0 : 1 ).sum() % 2;

    System.out.println( func.apply( "cat" ) );
}

Dyalog APL, 17 bytes
2|≢⍞∩'aeiouAEIOU'

TryAPL online!

Java 143 bytes
Output is a boolean which is true if the word is odd.
public static boolean isOdd(char c){
return c=='a'||c=='e'||c=='i'||c=='o'||c=='u';
}

public static boolean isOdd(String k){
  boolean y=false;
  for(char x:k.toLowerCase().toCharArray())
    if(isOdd(x))
      y=(y?false:true);
  return y;
}

Golfed:
boolean i(String k){boolean y=false;for(char c:k.toLowerCase().toCharArray())if(c=='a'||c=='e'||c=='i'||c=='o'||c=='u')y=!y;return y;}

Edit:

Fixed Case-sensitivity

Did you run this against the third test case?

Lithp, 56 bytes
#S::((& 1 (~ (length (split S (regex "[aeiou]" "i"))))))

Odd words: returns 1
Even words: returns 0

This was one of my test cases for developing my language. It was modified extensively after this challenge was posted to support running code such as this.

This is the same logic as the JavaScript response above. The language is a simplistic Lisp-like dialect with a fairly small interpreter.
Ungolfed:
(
    (var F #S::(
        (var L (split S (regex "[aeiou]" "i")))
        (& 1 (~ (length L)))
    ))
    (print (call F "brush"))
)

There is not currently an online repl to test this in, but there is a variation of this challenge in one of the provided examples that can be run with the interpreter.

Java, 128 bytes
boolean f(String k){return k.chars().flatMap(i->"aeiouAEIOU".contains(((char)i)+"")?IntStream.of(1):IntStream.of(0)).sum()%2>0;}

There's definitely a better way than using Instream.of(0) and Instream.of(1).

Pepe, 131 bytes
rEeEEeeeeErEeEEeeEeErEeEEeEeeErEeEEeEEEErEeEEEeEeEREeEeeeeeEREeeEeeeeeREEREEEerrEEEEEerEEeeREEEEReeReReREEeREEEEeeeRREeeeReEEEEReEE

Ouputs 0 for odd, 1 for even.
Try it online!

Powershell, 39 bytes
($args|sls "[aeiou]"-a).Matches.Count%2

Explanation:

Takes arguments from the predefined $args;
Selects all matches to vowel characters (sls is alias for Select-String. By default, matches are not case-sensitive);
Takes the Matches.Count, and %2 to check whether it's odd/even.

Test script:
$f = {

($args|sls "[aeiou]"-a).Matches.Count%2

}

@(
    ,("trees", $false)
    ,("brush", $true)
    ,("CAts", $true)
    ,("Savoie", $false)
    ,("rhythm", $false)

) | % {
    $s,$expected = $_
    $result = &$f $s
    "$($result-eq$expected): $result"
}

Output:
True: 0
True: 1
True: 1
True: 0
True: 0

Java 8: 88 bytes
s->s.chars().map(c->"aeiouAEIOU".contains((char)c+"")?-1:1).reduce(1,(x,y)->x*y)<0;

Try it online!

Dang it, I didn't see the older Java solution that used regex. Good job.

Python 3, 42 bytes
lambda x:sum(c in"aeiouAEIOU"for c in x)%2

Try it online!

brev, 62 bytes
(as-list odd?(c count(fn((as-list(c member x))"aeiouAEIOU"))))

Example:
(map
 (as-list odd? (c count (fn ((as-list (c member x)) "aeiouAEIOU"))))
 '("trees" "brush" "CAts" "Savoie" "even"))

=> (#f #t #t #f #f)

Perl 5 -p, 19 bytes
18 bytes for code; +1 byte for -p flag
$_=s/[aeiou]//gi%2

Try it online!
Prints 0 for even words; 1 for odd.

Pascal, 154 Bytes
This is a complete program according to ISO standard 7185 “Standard Pascal”.
program p(input,output);var n:integer;begin n:=0;repeat n:=n+ord(input^in['A','E','I','O','U','a','e','i','o','u']);get(input)until EOF;write(odd(n))end.

Ungolfed:
program oddWord(input, output);
var
    n: integer;
begin
    n := 0;

    repeat
    begin
        n := n + ord(input^ in ['A', 'E', 'I', 'O', 'U', 'a', 'e', 'i', 'o', 'u']);
        get(input);
    end
    until EOF(input);

    write(output, odd(n));
end.

It would be helpful to me if you explained why you are downvoting this answer.

Thunno 2, 3 bytes
ṃSɗ

Attempt This Online!
Explanation
ṃSɗ  # Implicit input
ṃ    # For each letter: 1 if vowel, 0 if consonant
 S   # Sum the resulting list of 1s and 0s
  ɗ  # Get its parity (mod 2)
     # Implicit output

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/


text:
Tips for golfing in Excel?
It's strange that I haven't seen this, as Excel seems to be a valid language for code golfing (despite its 'compiler' not being free).
Excel is somewhat of a wildcard in golfing, being good at golfing challenges of medium complexity, and sometimes simpler challenges as well. More often than not, Excel is good at challenges with string manipulation and mixed string-number manipulation.
What general tips do you have for golfing in Excel? I'm looking for ideas that can be applied to code golf problems in general that are at least somewhat specific to Excel (NOT VBA). Please, one tip per answer.

apparently [tag:cellular-automata] isn't something that is related to excel... :(

I was wondering if is it valid to create an UDF with VBA?

@danieltakeshi - no; well, not as an Excel answer - if you instead use Excel VBA and then call it from the immediate window, the activesheet or a subroutine, that it generally regarded as valid

If I want to make a Google Sheets tip, should I put it here or make a new question?

@Calculuswhiz - I would say it is probably best to add a new question for tips that are Google Sheets Specific, and include a link to this question in that response. Otherwise keeping functions that only available on one of the two platforms  - like let, lambda, arrayformula and regexreplace - may get really confusing.

Vectorization with Arrays
Whenever a function takes an array as an argument instead of a singleton, That function will also output an array with the result value to the corresponding indecies.
Example:
=LEN(A1)+LEN(B2)+LEN(C3)
could be replaced with
=SUM(LEN({A1,B2,C3}))

This process is usually called "vectorization" if my memory serves me well.

@ConorO'Brien Thanks! I changed my answer!

My current version of Excel seems to only allow constants inside of {}.  Cell references are not allowed.

Reference shorthand:
If your program is required to take multiple inputs, you may want to be able to scoop them all up at once. to read multiple cells as an array, one could do such as the example:
Example:
=len(A1)+Len(B1)+LEN(C1)
could be
=SUM(LEN(A1:C1))
=SUM(LEN(A1:C1 A2:C2 A3:C3))
could be
=SUM(LEN(A1:C3))
=SUM(LEN(A1:A1024))
could be
=SUM(LEN(A:A))
=SUM(LEN(A:A B:B C:C))
could be
=SUM(LEN(A:C))

I know this isn't a great tip, but it's specific enough to excel that I thought it should be included.

Concatenate shorthand:
The CONCATENATE function can be replaced with the & symbol 100% of the time, so long as the first argument is a string, or cell.
example:
CONCATENATE(A1,B1)

could be shortened to
A1&B1

In newer version of Excel (2016 or newer) the CONCAT function can be used for arrays and longer series of variables.
CONCAT(1:1)

Note, in newer Excel versions, CONCATENATE() was replaced by CONCAT().

Boolean Logic Shortcuts
Universal Set of Operators
0 => FALSE and any other number => TRUE, so we can exploit this fact with some arithmetic operators

Standard
Hacky
# Saved

NOT(A1)
A1=0
3, 1 if parenthesized

XOR(A1,B1)
A1<>B1
4

XOR(A1,B1,...)
A1=B1=...=0
3

NOT(XOR(A1,B1,...))
A1=B1=...
6 (XNOR)

OR(A1,B1,...)
A1+B1+...
4 or 2 (see note)

AND(A1,B1,...)
A1*B1*...
5

Note: This XOR only works if all argument values are the same nonzero number. You may have to "cast" a result (such as with OR) to a Boolean using ...>0
Operator precedence
You may have to add parentheses, depending on precedence.

Reference (:/ /,)
Negation (Prefix -)
Percent (%)
Exponentiation (^)
Multiplication/Division (*//) (AND)
Addition/Subtraction (+/-) (OR)
Concatenation (&)
Comparison (=, <, >, <=, >=, <>) (XOR/NOT)

Other Things

A blank cell evaluates to FALSE.

Converting a Number to Text:
This is a very simple tip, but it may be useful to some nonetheless...

If you need to convert a number to text from within a formula, use the concatenation operator to join two parts of the number as a string (i.e. 1&23).
If you need to convert a number to text for use by cell reference (i.e. A1), change the Number Format of the cell to Text to eliminate the need for extra bytes.
See the chart below for a comparison of number-to-text methods.

Quick Reference Chart:
+-------------------------------------------------------------------------------------+
|   | A               | B        | C         | D                | E                   |
|-------------------------------------------------------------------------------------|
| 1 | Formula         | Bytes    | Result    | ISTEXT(cell)¹    | ISTEXT(formula)²    |
|-------------------------------------------------------------------------------------|
| 2 | =TEXT(123,0)    | 12       | 123       | TRUE             | TRUE                |
| 3 | ="123"          | 6        | 123       | TRUE             | TRUE                |
| 4 | =1&23           | 5        | 123       | TRUE             | TRUE                |
| 5 | '123            | 4        | 123       | TRUE             | NOT VALID           |
| 6 | 123             | 3        | 123       | TRUE             | FALSE               |
| 7 | 123             | 3        | 123       | FALSE            | FALSE               |
+-------------------------------------------------------------------------------------+

Note: The result for cell C6 has been formatted as text, whereas the result for C7 has not.

¹ Denotes =ISTEXT(C2), =ISTEXT(C3), =ISTEXT(C4), etc.
² Denotes =ISTEXT(TEXT(123,0)), =ISTEXT("123"), =ISTEXT(1&23), etc.

Boolean Shorthand:
Instead of using the =TRUE() and =FALSE() functions, use =1=1 and =1=2.

Vectorization of arrays of cells:
The tip Vectorization with arrays Shows how you can golf down a function with an array by using specific formatting within the array. It is possible to do the same thing with cells, and will save you many many bytes in the long run. Say you have the following sheet:

And we want to find the highest shelf life of a fruit.
Without Vectorization, one might use the two formulas like so:

And this does give a correct answer, but the Score for this golf is Unconventional, and will probably not be accepted as widely. On top of that, this uses a drag down function (Ew), which makes for a confusing answer.
Instead, We can place the function in column D right on in with the formula in E2. To do this, you replace (in this case B2 and C2) your variables with arrays for the range you want to test. Thus, your formula becomes:

This saves you a few bytes as well as making your entry properly score-able.

Converting Types
To Number

Use a -- prefix.

--FALSE = 0, --TRUE = 1

Sometimes an arithmetic operator can be used to save steps later.

"2"-2 = 0, which can be used as an equality check.

To Boolean

Since numbers are implicitly Boolean-like, you may be able to avoid this.

0 => FALSE, Any other number => TRUE
Blank cell => FALSE

If you need it, you can use comparison operators.

A1<>0 => Non-zero to TRUE, A1>0 => Positive to TRUE.

To String

Concatenate either a blank cell or "" using the & operator.

Using BASE() and DECIMAL()
BASE takes a decimal number and converts it to another base. For example, =BASE(6873049,25) becomes "HELLO". You can do the reverse of this with =DECIMAL("HELLO",25). This is sometimes useful for restricted source problems, or can be used to compress a big number in a smaller base using a decimal number.

LET Function
LET allows you to define names within a function. For example, =LET(x,1,y,2,x+y) returns 3.  This allow you to define longer expressions with one character and reuse them within a formula. For example, LET(q,ROW(1:19),if(q>10,19-q,q)) lists the numbers from 1 to 10 and then back down to 1.
This sounds like a simple function but it has allowed golfing answers that were not possible before this was added to Excel.
There are functions like OFFSET and SUMIF that do not work entirely correctly on names that are not tied directly to cell references.
More info on LET

ISBLANK() Shorthand:
Instead of using =ISBLANK(A1), use =A1=0 to determine if a cell (i.e. A1) is empty.
Note: This shortcut will not work if cell A1 contains 0. In that case, you will need to use =A1="".